I am trying to validate the form using javascript. Once the code below executes I want to get the the php from an external script to run without a page load with a success message after can anyone help?
The script below works fine and pulling the notEmpty from a seperate function. I need the script to then:
1. if there are no errors produced then pull the php and transfer data from each value listed.
2. Display a success message
var year = document.getElementById('year');
var period = document.getElementById('period');
var live = document.getElementById('live');
var start = document.getElementById('start');
var todate = document.getElementById('todate');
var sdeadline = document.getElementById('sdeadline');
var cdeadline = document.getElementById('cdeadline');
var circ = document.getElementById('circ');
var line = document.getElementById('line');
// Check each input in the order that it appears in the form!
if(notEmpty(year, "Please fill in Year")){
if(notEmpty(period, "Please fill in Period")){
if(notEmpty(live, "Please fill in live Date")){
if(notEmpty(start, "Please fill in Start Date")){
if(notEmpty(todate, "Please fill in End Date")){
if(notEmpty(sdeadline, "Please fill in Supplier Deadline")){
if(notEmpty(cdeadline, "Please fill in Commerical Deadline")){
if(notEmpty(circ, "Please fill in Circulars Due")){
if(notEmpty(line, "Please fill in Line Listing Downloads")){
}}}}}}}}}
return false;
The ideea is to create a string with data that you want to transfer to php script:
var datasend = 'year='+year+'&period='+period+'&live='+live+ ...;
Then, if no errors, calls an Ajax function that sends via Post the string to server.
See a tutorial about: AJAX with POST and PHP
Related
I created a Google App Script that creates a form to allow users to choose their name from the dropdown list and it will direct them to the next page. On the next page, with their name and a little hint saying they need to clock out (see the image), as well as their options to choose whether they want to clock in or out.
After I run this script, I created a form with all those options on it. But the question is how to set a description that has the says last time they clock in is "mm/DD/yyyy" + you need to clock OUT" and vise versa.
How would I do this through Google script?
Here is the script:
function setUpForm() {
//Set up form
var form = FormApp.create('Clock In & Out System');
form.setTitle('Clock In Form');
//Set up first page
var item1 = form.addListItem()
.setTitle('Employee Name')
.setRequired(true);
var page2 = form.addPageBreakItem()
.setTitle('Fred');
//Set up second page (Fred)
var item2 = form.setTitle('Fred');
var item2a = form.addMultipleChoiceItem()
.setTitle('Clocking in or out?')
.setChoiceValues(["Clock in", "Clock out"])
.setRequired(true);
//Change last time clock in/out message and update reminder on what to do next
var page3 = form.addPageBreakItem()
.setTitle('Wilma')
.setGoToPage(FormApp.PageNavigationType.SUBMIT);
//Set up third page (Wilma)
var item3 = form.setTitle('Wilma');
var item3a = form.addMultipleChoiceItem()
.setTitle('Clocking in or out?')
.setChoiceValues(["Clock In", "Clock Out"])
.setRequired(true);
var page4 = form.addPageBreakItem()
.setTitle('Betty')
.setGoToPage(FormApp.PageNavigationType.SUBMIT);
//Setup forth page (Betty)
var item4 = form.setTitle('Betty')
var item4a = form.addMultipleChoiceItem()
.setTitle('Clocking in or out?')
.setChoiceValues(["Clock In", "Clock Out"])
.setRequired(true);
//Set up name choices on first page
item1.setChoices([
item1.createChoice("Fred", page2),
item1.createChoice("Wilma", page3),
item1.createChoice("Betty", page4)
]);
}
Here is the image:
The first thing that we should have in mind is that all the changes to the form should be made before respondent open the form.
One way to add the last time that the responded checked in message is to run a function that adds that message to the form. Maybe the most convenient way for most cases is to use an onFormSubmit trigger that updates the form item that should hold the "last clocked in" message.
NOTE: Script adopters should adapt it to their specific needs, but first they should understand what it does and how it does that.
For simplicity let say that we use a Title (Apps Script calls it Section Header) to hold the related message and that we have a form just with on Title and one Multiple Choice question and that the message should use a variables the clock in/out and the response timestamp. The following script will update the Title description on form submit, so the next time the user open the form to submit the clock in/out they will see the timestamp of the last time that they submitted a response. It should be added to a Script project bounded to the form.
/**
* Update help text of first section header on form submit
*
* #param Object e Form submit event object
* #param Object e.authMode A value from the ScriptApp.AuthMode enum.
* #param Object e.response A FormResponse object, representing the user's response to the form as a whole.
* #param Object e.source A Form object, representing the Google Forms file to which the script is bound.
* #param Object e.triggerUid ID of trigger that produced this event.
*/
function updateHelpText(e) {
// Get section headers.
var formItems = e.source.getItems(FormApp.ItemType.SECTION_HEADER);
// Get response timestamp
var timestamp = e.response.getTimestamp();
// Get script timezone
var timeZone = Session.getScriptTimeZone();
// Set timestamp format
var format = 'mm/dd/yyyy hh:mm';
// Get the first section header. This form item will hold the message.
var item = formItems[0];
// Get clocked type
var type = e.response.getItemResponses()[0].getResponse();
// Set message
var message = Utilities.formatString('The last time you %s was %s',
type,
Utilities.formatDate(timestamp, timeZone, format));
// Add message to section header
item.setHelpText(message);
}
/**
* Auxiliary function to validate on form submit function
*
*/
function test(){
// Create a form response
var form = FormApp.getActiveForm();
var items = form.getItems();
var x = items[1].getTitle();
var formResponse = form.createResponse();
formResponse
.withItemResponse(
items[1].asMultipleChoiceItem().createResponse('Clock in')
);
// Create on form submit event object
var e = {}; // Form submit event object
e.authMode = ScriptApp.AuthMode.FULL; // A value from the ScriptApp.AuthMode enum.
e.source = form; // A Form object, representing the Google Forms file to which the script is bound.
e.response = formResponse.submit(); // A FormResponse object, representing the user's response to the form as a whole.
e.triggerUid = '00000000'; // ID of trigger that produced this event.
// Call the on form submit function
updateHelpText(e);
}
Once the above code is added to the form script project, add a trigger following the instructions on Installable triggers.
To adapt the above for the OP case, the adopters could add some logic to replace the 0 indexes by the corresponding indexes for the Title and the Clock in or Clock out? form items and item responses accordingly. Let say that i and j are used to hold the corresponding indexes, then beside adding the code to set that indexes on the following lines should be replaced the 0 indexes by i and j accordingly:
// Get the first section header. This form item will hold the message.
var item = formItems[i];
// Get clocked type
var type = e.response.getItemResponses()[j].getResponse();
This is a two part question:
I have google sheet with a linked Form. When the form is submitted I want the responses from the form to be copied to another google sheet where I intend to change and reformat and then send via email. The script below is what i have currently written and it has a trigger set up onFormSubmit. However, I keep getting the follow error:
TypeError: Cannot read property "Values" from undefined. (line 7, file "Code")
Code below:
function formSubmitReply(e)
{
var t = "1g-wIs6nGxu3mJYA1vKtPCxBLCsvh1upeVGbCokOOTIw";
var tName = "AggregationOutput";
//Get information from form and set as variables
var email = e.Values[2];
var name = e.Values[3];
// Get template, copy it as a new temp, and save the Doc’s id
var tcopyId = SpreadsheetApp.openById(t).copy(tName+' for '+name).getId();
// Open the temporary document & copy form responses into template copy response sheet
var copyt = SpreadsheetApp.openById (tcopyId);
var copyts = copyt.getSheetByName('Resp');
// Transfers Data from Form Responses to Temporary file
copyts.getRange('A3').setValue(name);
//Sends copy of template in an email as an excel file
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + copyt.getId();
var subject = 'Aggregaton Output for' + name;
var body = url
MailApp.sendEmail(email, subject, body);
// Deletes temp file
DriveApp.getFileById(tcopyId).setTrashed(true);
}
Part two of my question, even if I can get the code to work what would you recommend when a question is skipped in the form - won't this change the array from e.values. The issue with using the last row as a problem is that I want people to go back and edit responses on the form and then resubmit which means the last row isn't always the row used.
Any and all help is appreciated.
For Part 1, try this:
function formSubmitReply(e)
{
var t = "1g-wIs6nGxu3mJYA1vKtPCxBLCsvh1upeVGbCokOOTIw";
var tName = "AggregationOutput";
//Get information from form and set as variables
var itemResponses = e.response.getItemResponses();
var email = itemResponses[2].getResponse();
var name = itemResponses[3].getResponse();
// Get template, copy it as a new temp, and save the Doc’s id
var tcopyId = SpreadsheetApp.openById(t).copy(tName+' for '+name).getId();
// Open the temporary document & copy form responses into template copy response sheet
var copyt = SpreadsheetApp.openById (tcopyId);
var copyts = copyt.getSheetByName('Resp');
// Transfers Data from Form Responses to Temporary file
copyts.getRange('A3').setValue(name);
//Sends copy of template in an email as an excel file
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + copyt.getId();
var subject = 'Aggregaton Output for' + name;
var body = url
MailApp.sendEmail(email, subject, body);
// Deletes temp file
DriveApp.getFileById(tcopyId).setTrashed(true);
}
Question 1:
The error you get is due to a wrong syntax, values (All small, not Values)
var email = e.values[2];
var name = e.values[3];
Question 2:
When the question is skipped the value of the response is blank. So if an email is left blank e.values[2] would still refer to the email field in your form, but will have no value in it.
If you have edit later option activated on the form, the edited responses will only be present in the e.values array. So if they update their email ID only, e.values[2] = "updated Email ID" and e.value[0-1,3-end] = Empty/blank.
To figure out if the submission is new entry or edited entry you can use e.range to figure out where the responses are going to be added in the "form Response" sheet. And you can mirror that range in your "resp" sheet to keep it updated the same way as form response sheet.
I've been trying Google Apps Script a submit button using data validation ranges, however I'm struggling.
function submit2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var IBR = ss.getSheetByName('IBR');
var lastColumn = IBR.getLastColumn()+1;
var cell = IBR.getRange(7,5,7);
var total = ss.getSheetByName('MS').getRange('G2:G13').getValue();
cell.setValue(total);
}
Here's picture of data and below the validation, the submit image once click should reflect that date and take numbers and put them on a second page
And there's where second page would receive the information
I'm working on designing a new process for internal job submission for work which now involves javascript for it to work effectively.
Scripting is not my forte but that hasn't deterred me, I've been able to find three different pieces of code to insert into the various buttons and fields and they've done what they should do. My problem is I need to combine some of these for an extra validation on submit. This is where I fall short.
The process:
There is a required field in the form which currently runs a custom validation script to check a certain format specific to the code needed for a job. This runs well and I was even able to add an alert and hint images that show when incorrect and a little tick when correct. Beautiful.
The second major part of the form is in the submit button. I hacked together a code which not only emails the submitted form with fields as the subject line but also makes all fields read only before doing so. Brilliant.
Here's the messy part. A user can enter a correct or incorrect required code and the validator does its bit but that doesn't stop them from still submitting the form. Fine. I can fix that by running the validator again on the submit button so it not only gives user feedback on blur of the required field but again validates on submit so if the field is incorrect the submit stops until the user has the correct value in the field. This is where my knowledge stops like a cliff edge and I can't seem to build a bridge.
I've tried numerous ways of calling the field value then just running the same validation script with some if and else statements but it just doesn't work.
Can anyone help? Current code for submission button below but keep in mind that the validation section of this code is also attached to the required field directly (this affects it?):
function OR_Stuff() {
var ProjectTitle = getField("ProjectTitle").value;
var Brand = getField("Brand").value;
var Name = getField("Name").value;
var Noosh = getField("INT_NooshCode").value;
for (var i = 0 ; i < this.numFields ; i++) {
var f = this.getField(this.getNthFieldName(i));
if (f.type != "Submit") // Change f.type to button name in form that the action is applied to
{
f.readonly = true;
}
}
this.mailDoc({
cTo: "email",
cBcc: "email",
cSubject: "NEW JOB: "+Brand+" - "+ProjectTitle+" - "+Noosh,
cMsg: "Thanks "+Name+" for sending through this job."
});
}
var re = /^\d{5}[A-Z]\d{2}$/
if (re.test(INT_NooshCode.value) == false) {
this.getField("RequiredAlert").display = display.visible;
this.getField("NooshTick").display = display.hidden;
app.alert("Sorry, we can't start a project without a Noosh code. \n\nPlease enter a valid Noosh code EG: 34256P02");
}
else {
OR_Stuff();
}
The site I'm building requires two identical forms on each page that sends the data to the same place, one form in the sidebar, and the other form in the footer. All I am trying for is light weight javascript that will kick out an error message if the user tries to submit the form when any or all of the required fields are left blank. Here's my issue:
Everything works as I intended for the sidebar form, however the javascript isn't treating the form placed in the footer as it does the sidebar form. When all form requirements are satisfied within form #2, it doesn't process the data and only shows the error message because I'm assuming it thinks the form is blank since the other form is blank.
I understand that there's likely a conflict of interest going on and the javascript engine is confused due to the input id's being exactly the same (they nned to be for this project since it involves salesforce). I already have bullet proof spam protection built into the php file that processes the form data, I just need some basic client-side validation to prevent the user from submitting the forms with any missing 'required' data. Like I said, everything works as I want it to with the first form, but not at all with the second. Can anyone help me with this because I don't really know where to start. I'm still relatively new to working with javascript so I apologize if what I have written is mess.
form #1 (in the sidebar)
$("#messageSent").hide();
$("#form1").submit(function(ev){
ev.preventDefault();
var fname = $('#first_name').val();
var lname = $('#last_name').val();
var phone = $('#phone').val();
var email = $('#email').val();
var condition = $('#condition').val();
var relationship = $('#relationship').val();
var inquiry = $('#inquiry').val();
if(fname && lname && phone && email && condition && relationship && inquiry){
$.ajax({
type: "POST",
url: $(this).attr('action'),
data: $("#form1").serialize(), // serializes the form's elements.
success: function(data)
{
data = $("#messageSent").fadeIn(),
$("#form1").fadeOut()
}
});
} else {
alert("You must complete the required fields before submitting the form.")
return false;
}
});
form #2 (in the footer section)
$('#messageSent-bottom').hide();
$("#form2").submit(function(ev){
ev.preventDefault();
var fname = $('#first_name').val();
var lname = $('#last_name').val();
var phone = $('#phone').val();
var email = $('#email').val();
var condition = $('#condition').val();
var relationship = $('#relationship').val();
var inquiry = $('#inquiry').val();
if(fname && lname && phone && email && condition && relationship && inquiry){
$.ajax({
type: "POST",
url: $(this).attr('action'),
data: $("#form2").serialize(), // serializes the form's elements.
success: function(data){
data = $("#messageSent-bottom").fadeIn(),
$("#form2").fadeOut()
}
});
} else {
alert("You must complete the required fields before submitting the form.")
return false;
}
});
When you use $('#the-id'), it only grabs the first one on the page (since you really shouldn't have multiple elements with the same id).
You could try adding something like the following:
var fname = $(this).find('#first_name').val();
This will keep it in the context of the current form. Though I would probably just prefix the ids since you already have separate submit functions.