Google web app server returns null even though logger.log confirms theirs data - google-apps-script

I currently have a google web app that checks to see if the a value (predefined from dropdown list so it will always been in the column") is in a column, if it is, it returns information about that value. however i am trying to update it so if the value is not found in the column(user entered value), it searches a second column to see if anyone has entered that value before. the issue i am having is once it finds the user entered value, it collects the value of the cells adjacent to it and flicks it back to the client side HTML javascript, the client side is seeing it as null. It's currently working fine for the first section which uses the predefined drop down choices. it's still finding the correct information, its just the client side for some reason cannot see it. I am abit of a novice when it comes to coding so any help anyone could provide would be GREATLY appreciated.
function sendFleet(e){ // This code sends the dropdown value to the server side
e.preventDefault();
var fleet = document.getElementById("Fleet").value
document.getElementById('photostatus').innerHTML = "Waiting For Photo.."
if(fleet != "Not on this list?"){
var data1 = {
FleetNumber: document.getElementById("Fleet").value,
}
google.script.run.withSuccessHandler(consoleyay)
.sendFleet(data1)
}
else if(fleet == "Not on this list?"){
console.log("right area")
document.getElementById("Rego").innerHTML= "Rego"
document.getElementById("NOLF").style.display=""
document.getElementById("NOLR").style.display=""
document.getElementById("NOLB").style.display=""
document.getElementById("NOLS").style.display=""
document.getElementById("Fleet").style.display="none"
document.getElementById("Rego").style.display="none"
}
}
function SENDFLEET(e){ // This code sends a user entered value to the server.
e.preventDefault();
var fleet = document.getElementById("NOLF").value
document.getElementById('photostatus').innerHTML = "Waiting For Photo.."
var data1 = {
FleetNumber: document.getElementById("NOLF").value,
}
google.script.run.withSuccessHandler(consoleyay)
.sendFleet(data1)
}
function sendFleet(data1){
var Fleet = data1.FleetNumber
var FleetListing = SpreadsheetApp.openById("1ufyN6mgzdHXoYbVC6TENcc7V2zGxdQtp0ctaCR-kiEw").getSheetByName("FleetListing")
var data2 = FleetListing.getRange(3,3,FleetListing.getLastRow(),1).getValues().reduce(function (a, b) { //flatten the 2D array obtained by .getValues()
return a.concat(b);
});;
var fleetdata = FleetListing.getRange(3,1,FleetListing.getLastRow(),8).getValues()
var Search1 = data2.indexOf(Fleet)
var site = ""
var type = ""
var fleet = ""
var rego = ""
var insidev = ""
var outsidev = ""
var insideb = ""
var outsideb = ""
var search = ""
Logger.log(Search1)
if(Search1 != "-1"){
Logger.log("shouldn't be here")
site = fleetdata[Search1][0]
type = fleetdata[Search1][1]
fleet = fleetdata[Search1][2]
rego = fleetdata[Search1][3]
insidev = fleetdata[Search1][4]
outsidev = fleetdata[Search1][5]
insideb = fleetdata[Search1][6]
outsideb = fleetdata[Search1][7]
search = Search1
}
else if(Search1 == "-1"){
var MTL = SpreadsheetApp.openById("1ufyN6mgzdHXoYbVC6TENcc7V2zGxdQtp0ctaCR-kiEw").getSheetByName("MasterToLocal")
var data3 = MTL.getRange(1,3,MTL.getLastRow(),1).getValues().reduce(function (c, d) { //flatten the 2D array obtained by .getValues()
return c.concat(d);
});;
var fleetdata1 = MTL.getRange(1,1,MTL.getLastRow(),8).getValues()
var Search2 = data3.indexOf(Fleet)
Logger.log("lukes okay")
Logger.log(Fleet)
Logger.log(Search2)
Logger.log(data3)
if(Search2 != "-1"){
Logger.log("Test start")
site = fleetdata1[Search2][0]
Logger.log(site)
type = fleetdata1[Search2][1]
fleet = fleetdata1[Search2][2]
rego = fleetdata1[Search2][3]
insidev = fleetdata1[Search2][4]
outsidev = fleetdata1[Search2][5]
insideb = fleetdata1[Search2][6]
outsideb = fleetdata1[Search2][7]
search = Search2
Logger.log("Test Finish")
}
}
return [site,type,fleet,rego,insidev,outsidev,insideb,outsideb,search]
}
function consoleyay(details){ // this is the code that handles the response from the server.
console.log(details)
var site = document.getElementById("Site").value
console.log(site)
console.log("issues 1")
var Type = document.getElementById("Type").value
console.log("issue 2")
var fleet = details[2]
var rego = details[3]
var inv = details[4]
var outv = details[5]
console.log("before bg")
var inb = details[6]
var outb = details[7]
console.log("after BG")
var Search1 = details[8]

Solved the issue. Instead of using .getValue, i used .getDisplayValue which will return the date as a string.

Related

Google forms list items with dynamic goto section

I found this answer posted here earlier.
function GoToPage() {
var form = FormApp.openById('MY FORM');
var spreadsheet = SpreadsheetApp.openById("MY SPREADSHEET");
var sheet = spreadsheet.getSheetByName("MY SHEET");
var list = form.getItemById("MY MULTIPLE CHOICE ID").asListItem()
var pagebreak01 = form.getItemById("PAGE BREAK ID 1").asPageBreakItem();
var pagebreak02 = form.getItemById("PAGE BREAK ID 2").asPageBreakItem();
var pagebreak03 = form.getItemById("PAGE BREAK ID 3").asPageBreakItem();
var choice1 = sheet.getRange("RANGE 1 FROM MY SHEET").getValues();
var choice2 = sheet.getRange("RANGE 2 FROM MY SHEET").getValues();
var choice3 = sheet.getRange("RANGE 3 FROM MY SHEET").getValues();
list.setChoices([
list.createChoice(choice1, pagebreak01),
list.createChoice(choice2, pagebreak02),
list.createChoice(choice3, pagebreak03)]);
}
when using a range larger than 1 in the choice# variables, this makes just one choice with all the items in the range separated by commas. how can I use this to make a list of choices that has a dynamic range?
My exact choices should be:
"** Add Location **" , goto newLocation section of form.
location 1, goto next section.
location 2, goto next section.
location 3, ect....
If you select new location and fill out the form to add a new location the script then adds that location name to the choices for the next time you fill out the form. so this list is continually growing larger.
function updateForm() {
var locationForm = form.getItemById("413015265").asListItem();
var equipmentForm = form.getItemById("2123556695").asListItem();
var newLocation = form.getItemById('231469190').asPageBreakItem();
var newItem = form.getItemById('90044295').asPageBreakItem();
var gotoIssue = form.getItemById('1493817332').asPageBreakItem();
var gotoLocation = form.getItemById('1425783734').asPageBreakItem();
var locations = tblLocations.getRange(2,2,tblLocations.getLastRow()-1,1).getValues();
var items = tblItems.getRange(2,2,tblItems.getLastRow()-1,1).getValues();
items = items.sort();
locations = locations.sort();
locationForm.setChoices([
locationForm.createChoice("** Add Location **",newLocation),
locationForm.createChoice(locations,gotoIssue)
]);
equipmentForm.setChoices([
equipmentForm.createChoice("** Add Item **",newItem),
equipmentForm.createChoice(items,gotoLocation)
]);
}
after running the above script I ended up with only 2 choices. 1 new location/item entry which works correctly, and 1 entry with all the current locations/items in the spreadsheet already, separated by commas. Can i just run a foreach loop inside the setChoices command?
function updateForm() {
var locationForm = form.getItemById("413015265").asListItem();
var equipmentForm = form.getItemById("2123556695").asListItem();
var newLocation = form.getItemById('231469190').asPageBreakItem();
var newItem = form.getItemById('90044295').asPageBreakItem();
var gotoIssue = form.getItemById('1493817332').asPageBreakItem();
var gotoLocation = form.getItemById('1425783734').asPageBreakItem();
var locations = tblLocations.getRange(2,2,tblLocations.getLastRow()-1,1).getValues();
var items = tblItems.getRange(2,2,tblItems.getLastRow()-1,1).getValues();
var locationChoices = [];
var itemChoices = [];
locationChoices[0] = locationForm.createChoice("** Add Location **",newLocation);
itemChoices[0] = equipmentForm.createChoice("** Add Item **",newItem);
items = items.sort();
locations = locations.sort();
for (var i=0;i<tblLocations.getLastRow()-1;i++){
locationChoices[i+1]= locationForm.createChoice(locations[i],gotoIssue);
}
locationForm.setChoices(locationChoices);
for (var i=0;i<tblItems.getLastRow()-1;i++){
itemChoices[i+1]= equipmentForm.createChoice(items[i],gotoLocation);
}
equipmentForm.setChoices(itemChoices);
}
I was able to figure it out. It's probably not the most beautiful solution but it works. :)

How to pull data from multiple Mailchimp endpoints?

The code below pulls data from the Mailchimp API Reports endpoint and adding it to Sheets.
I would like to add some more data from other endpoints (like fields from the "List/Audience" endpoint: member_count, total_contacts i.e.) but don't have a slick solution to this.
What's the best practice/solution here? Can this task be kept in the same function or is a separate function preferable?
I'm new in this area so bear with me :)
function chimpCampaigns() {
var API_KEY = 'X'; // MailChimp API Key
var REPORT_START_DATE = '2018-01-01 15:54:00'; // Report Start Date (ex. when you sent your first MailChimp Newsletter)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("CampaignData");
var dc = API_KEY.split('-')[1];
var api = 'https://'+ dc +'.api.mailchimp.com/3.0';
var count = 100; // Max rows to return
var campaignList = '/campaigns?&count='+count+'&since_send_time='+REPORT_START_DATE
var options = {"headers": {"authorization": 'apikey '+API_KEY}};
var apiCall = function(endpoint){
apiResponseCampaigns = UrlFetchApp.fetch(api+endpoint,options);
json = JSON.parse(apiResponseCampaigns);
return json
}
var campaigns = apiCall(campaignList);
var total = campaigns.total_items;
var campaignData = campaigns.campaigns;
if (campaignData) {
sheet.clear(); // Clear MailChimp data in Spreadsheet
// Append Column Headers
sheet.appendRow(["Sent Time", "Campaign ID", "Audience", "Campaign Title", "Subject Line", "Emails Sent", "Abuse Reports", "Unsubscribed", "Unsubscribe Rate", "Hard Bounces", "Soft Bounces", "Bounces Total", "Syntax Errors", "Forwards Count", "Forwards Opens", "Opens Total", "Unique Opens", "Open Rate", "Last Open", "Clicks Total", "Unique Clicks","Unique Subscriber Clicks", "Click Rate", "Last Click"]);
}
for (i=0; i< campaignData.length; i++){
var c = campaignData[i];
var cid = c.id;
var title = c.title;
var subject = c.subject;
var send_time = c.send_time;
if (send_time){
apiResponseReports = UrlFetchApp.fetch('https://'+ dc +'.api.mailchimp.com/3.0/reports/'+cid,options);
reports = JSON.parse(apiResponseReports);
reportsSendTime = reports.send_time;
if(reportsSendTime){
var campaign_title = c.settings.title;
var subject_line = c.settings.subject_line;
var emails_sent = reports.emails_sent;
var list_name = reports.list_name;
var fields = reports.fields;
var abuse_reports = reports.abuse_reports;
var unsubscribed = reports.unsubscribed;
var unsubscribe_rate = unsubscribed/emails_sent;
var hard_bounces = reports.bounces.hard_bounces;
var soft_bounces = reports.bounces.soft_bounces;
var bounces = hard_bounces+soft_bounces;
var syntax_errors = reports.bounces.syntax_errors;
var forwards_count = reports.forwards.forwards_count;
var forwards_opens = reports.forwards.forwards_opens;
var opens_total = reports.opens.opens_total;
var unique_opens = reports.opens.unique_opens;
var open_rate = reports.opens.open_rate;
var last_open = reports.opens.last_open;
var clicks_total = reports.clicks.clicks_total;
var unique_clicks = reports.clicks.unique_clicks;
var unique_subscriber_clicks = reports.clicks.unique_subscriber_clicks;
var click_rate = reports.clicks.click_rate;
var last_click = reports.clicks.last_click;
// the report array is how each row will appear on the spreadsheet
var report = [send_time, fields, cid, list_name, campaign_title, emails_sent, subject_line, abuse_reports, unsubscribed, unsubscribe_rate, hard_bounces, soft_bounces, bounces, syntax_errors, forwards_count, forwards_opens, opens_total, unique_opens, open_rate, last_open, clicks_total, unique_clicks, unique_subscriber_clicks, click_rate, last_click];
sheet.appendRow(report);
}
}
}
}
You can call each endpoint in succession using the error-first pattern. More on this here.
If your previous call returns data and doesn't error out, you pass the next function as a callback, etc.
In the example below, I've omitted the logic that builds URL endpoint, query-string, and the 'options' object as these can simply be borrowed from your code.
Basically, you define a function with a callback parameter for each API endpoint.
Whenever you need to call multiple endpoints, you create a 3rd function that calls them in succession, passing each new function call as a parameter to the previous one.
The inner functions will still have access to the outer scope so you can combine data from multiple endpoints after the last call is executed (provided you assign unique names to the returned data - 'campaigns', 'reports', etc)
//function for the 'campaings' endpoint
function getCampaings(options, callback) {
//API call
var response = UrlFetchApp.fetch(campaignsEndpoint, options);
if (res.getStatusCode() == 200) {
var campaigns = JSON.parse(res.getContentText());
callback(false, campaigns);
} else {
callback("Error: Server responded with the status code of " + res.getStatusCode());
}
}
After creating the function for calling the 'reports' endpoint using the same approach, combine calls in the 3rd function.
function getCampaignsAndReports(){
var combinedData = {};
getCampaigns(options, function(err, campaigns){
if (!err && campaigns) {
//Call is successful - proceed to the next call
getReports(options, function(err, reports){
//Call successful
if (!err && reports) {
//Proceed to the next call or combine data from
//multiple endpoints
combinedData.campaigns = campaigns.campaigns;
combinedData.reports = reports.reports;
//write to sheet
//...
} else {
//Error calling reports endpoint
throw err;
}
});
} else {
//Error calling 'campaigns' endpoint. Throw error or write
//another function to show it to the user
throw err;
}
});
}
This may vary depending on how the MailChimp API data is structured so please change the code accordingly. Also, if you need to call the 'reports' endpoint multiple times for each entry in the 'campaings' endpoint, you can change your function to handle multiple request (options) object using UrlFetchApp.fetchAll(request[]). More on this here. Calling this method will return multiple response objects that you can iterate over.

How can I present customer data from spreadsheet into form in app maker for update?

I have struggling to present available data for selected customer from spreadsheet into app maker form incase staff want to change it or update empty fields.
Client side code:
function getDetails() {
var props = app.currentPage.properties;
var page = app.pages.Search;
var Channel = app.datasources.Update.items;
var Customer = page.descendants.Sheets.value;
props.Loading = true;
props.Error = null;
google.script.run
.withFailureHandler(function(error) {
props.Loading = false;
props.Error = JSON.stringify(error);
console.error(error);
})
.withSuccessHandler(function(Channel) {
props.Loading = false;
page.Channel = Channel;
var items = [];
items = getChannels(props.SelectedSheet);
Channel.items.load(); // this line dosen't work and it doesn't load the data into form
if (Channel && Channel.length > 0) {
page.SelectedSheet = Channel[0];
} })
.getDetails(props.SelectedSheet);
}
Server side code:
function getDetails()(customer){
var spreadSheet = SpreadsheetApp.openById("***").getSheetByName('TRACKER');
var data=spreadSheet.getDataRange().getValues();
var channels = [];
var Name = customer;
var string1 = Name;
var array1 = string1.split(";"); // in here I extract row number belong to customer to get data
var destrow = [];
destrow.push(data[array1[0]][0],data[array1[0]][1],data[array1[0]][2],data[array1[0]][3],data[array1[0]][4],data[array1[0]][5]);
channels.push(destrow);
// return channels;
return channels.map(function(Channel){
return Channel;}); // return array of field data to presented in app maker form
}
Thank you for any answer or suggestion.
Cheers
In theory, this code should throw exception, since Channel is array and array doesn't have load method:
function getDetails() {
...
var Channel = app.datasources.Update.items;
...
// your first Channel variable is never used and is overridden with
// Channel callback parameter
.withSuccessHandler(function(Channel) {
// this line does nothing, since all App Maker objects are sealed
page.Channel = Channel;
// TypeError: load is not a function
Channel.items.load();
...
}
It is not clear from you code, what you are trying to do... Try to debug it and look into browser console more often (F12 or Ctrl + Shift + J).
Further reading:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal

Is there a limit to how many G-Forms i can link to a singe google spreadshee?

I have a script that is designed to create about 120 forms and link them to a single spreadsheet where I will analyze the data. I don't have any issues with the script until my spreadsheet has about a dozen forms linked to it. Then I get an error saying the destination ID is invalid, after logging the id, and entering it manually into a url I see no issues with the ID....
var ssSummaryId = '******redacted*******';
var form = FormApp.create('RM#' + rmNumber).setDestination(FormApp.DestinationType.SPREADSHEET, ssSummaryId);
form.setDescription(valuesSummary[ii][2])
.setConfirmationMessage('Thanks for the update on room ' + rmNumber)
.setShowLinkToRespondAgain(false);
// form.setDestination(FormApp.DestinationType.SPREADSHEET, ssSummaryId);
var formId = form.getId();
var formUrl = form.getPublishedUrl();
EDIT I'm adding my complete script and some additional info, just in case someone wants to check my code out and point out all it rookie mistakes.
I'm using Google scripts to build a spreadsheet and then create 120 slightly altered Google forms that are linked to a single spreadsheet, all the responses are by design on separate sheets named "form responses n". I consistently hit a wall once I exceed 10 forms linked to one sheet. Note; in initial testing I remember having a spreadsheet with 46 forms (and therefore sheets) linked to it. As you can see in the code below, I have the app restart from where it's left off after every 5 forms are created, so I'm not getting any 'extended runtime errors". Just the error below, typically after the script runs twice from Google Scripts IDE.
I'm just finally getting the hand of basic javascript after years of using and modifying js in web developing. So I apologize in advanced for the poor code.
Failed to set response destination. Verify the destination ID and try again. (line 54, file "Code")
function spreadsheet_builder() {
var ssSummaryId = '<<REDACTED>>';
var ssFormDataId = '<<REDACTED>>';
var batchSize = 5;
var buildStatus = false;
var ssSummary = SpreadsheetApp.openById(ssSummaryId);
SpreadsheetApp.setActiveSpreadsheet(ssSummary);
if (ssSummary.getSheetByName('Summary') == null) {
var sheetSummary = ssSummary.getSheetByName('Sheet1');
} else {
var sheetSummary = ssSummary.getSheetByName('Summary');
}
var rangeSummary = sheetSummary.getDataRange();
var valuesSummary = rangeSummary.getValues();
buildStatus = get_last_position(valuesSummary, buildStatus); //either returns last position in array or 'true' if task is complete
if (buildStatus != true || buildStatus > 0) {
var formCreation = [];
var formData = get_form_data(ssFormDataId); // Get form questions from form Data ss, might be better to keep everything on the same sheet
batchSize = buildStatus + batchSize;
for ( var ii = buildStatus; ii < batchSize; ii++ ) {
if (valuesSummary[ii][1] != '') {
var formCreationReturn = form_builder(formData, valuesSummary, ii, ssSummaryId);
formCreation.push(formCreationReturn);
}
}
var aSum = [ssSummary, sheetSummary, rangeSummary];
final_storing_operation(formCreation, aSum, buildStatus);
}
if (sheetSummary.getName() != 'Summary') {
SpreadsheetApp.setActiveSpreadsheet(ssSummary);
sheetSummary.activate().setName('Summary');
sheetSummary.setFrozenColumns(3);
sheetSummary.setFrozenRows(1);
sheetSummary.hideColumns(1);
//var sSumIndex = sheetSummary.getIndex();
}
SpreadsheetApp.setActiveSpreadsheet(ssSummary);
sheetSummary.activate();
ssSummary.moveActiveSheet(1);
}
function form_builder(formData, valuesSummary, ii, ssSummaryId) {
var lastFormCreated = ii;
var rmNumber = valuesSummary[ii][1];
var form = FormApp.create('RM#' + rmNumber).setDestination(FormApp.DestinationType.SPREADSHEET, ssSummaryId);
form.setDescription(valuesSummary[ii][2])
.setConfirmationMessage('Thanks for the update on room ' + rmNumber)
.setShowLinkToRespondAgain(false);
// form.setDestination(FormApp.DestinationType.SPREADSHEET, ssSummaryId);
var formId = form.getId();
var formUrl = form.getPublishedUrl();
var sectionHeader = 'SECTION_HEADER'; //preformatted form question types.
var list = 'LIST';
var paragraphText = 'PARAGRAPH_TEXT';
for (var j = 1; j < formData.length; j++) { //top row is header
switch (formData[j][0]) {
case sectionHeader:
form.addSectionHeaderItem().setTitle(formData[j][1]);
break;
case list:
var item = form.addListItem();
item.setTitle(formData[j][1]).setHelpText(formData[j][2]);
item.setChoices([
item.createChoice(formData[j][3]),
item.createChoice(formData[j][4]),
item.createChoice(formData[j][5])
]);
break;
case paragraphText:
form.addParagraphTextItem().setTitle(formData[j][1]);
break;
default:
form.addSectionHeaderItem().setTitle('OOPS u\'don MESSED up');
break;
}
}
return [formId, formUrl, lastFormCreated, rmNumber];
}
function final_storing_operation(formCreation, aSum, buildStatus) {
SpreadsheetApp.setActiveSpreadsheet(aSum[0]);
aSum[1].activate();
var startRow = formCreation[0][2] + 1;
var newRange = aSum[1].getRange(startRow, 1, formCreation.length, 2); //row, clmn, rows, columns
var newValues = [];
for ( var ij = 0; ij < formCreation.length; ij++) {
var values = [formCreation[ij][0], "\=HYPERLINK(\"" + formCreation[ij][1] + "\", \"RM#" + formCreation[ij][3] + "\")"];
newValues.push(values);
}
newRange.setValues(newValues);
}
function get_last_position (valuesSummary, buildStatus) {
var rowPos = 1; // start at 1 to ignore headers
while (valuesSummary[rowPos][1] != '') {
if (valuesSummary[rowPos][0] == '') {
return rowPos;
}
rowPos++;
}
if(valuesSummary[rowPos][0] != '' && valuesSummary[rowPos][1] != '') {
buildStatus = true;
return buildStatus;
}
}
function get_form_data (ssFormDataId) {
var ssFormData = SpreadsheetApp.openById(ssFormDataId);
SpreadsheetApp.setActiveSpreadsheet(ssFormData);
var sheetFormData = ssFormData.getSheets()[0];
var rangeFormData = sheetFormData.getDataRange();
var valuesFormData = rangeFormData.getValues();
return valuesFormData;
}
As an alternative, you could create the forms, and intentionally not link them to a spreadsheet, then have some code that looped through every form, and extracted the data. You'd probably want to put the forms into their own folder.
Or, you'd need to build a form with Apps Script HTML Service, embed it into a Apps Script Gadget in a Google Site, and have everyone fill out the form from Sites.

Uploading files on Google Sites - file cabinet, list page - doPost issues, unexpected error

I had this script working, but a few weeks ago it suddenly stopped - I assumed I made some programming error but I've been unable to debug this for weeks.
I want a script on google sites that allows someone to upload a file (and some other information, like its name) and have the script attach it to a new file cabinet page and then update a list page with the new page's information.
I used parts of code from an old forum post, updating where I needed to. I am not opposed to rewriting if someone knows of a simpler way to do this.
Thanks!
EDIT: the problem seems to be in the doPost(e) function - after hitting submit, nothing happens, the gadget goes blank and I get the error message: "An unexpected error occurred."
function doGet(e){
return getUi(e);
}
function getUi(e) {
//create user interface for uploading information
var app = UiApp.createApplication().setTitle('File Upload');
var form = app.createFormPanel().setId('form').setEncoding('multipart/form-data');
//create grid to store information
var formContent = app.createGrid().resize(6,2);
formContent.setText(0,0,'File Name: ');
var fileName = app.createTextBox().setName('fileName').setId('fileName');
formContent.setWidget(0,1,fileName);
var fileUpload = app.createFileUpload().setName('fileUpload').setId('fileUpload');
formContent.setWidget(1,1,fileUpload);
formContent.setWidget(2,0,app.createLabel('Short Description: '));
var fileDescription = app.createTextBox().setName('fileDescription').setId('fileDescription');
formContent.setWidget(2,1,fileDescription);
formContent.setText(3,0,'Level: ');
var level = app.createListBox().setName('level').setId('level').addItem('Introductory').addItem('Intermediate').addItem('Advanced');
formContent.setWidget(3,1,level);
formContent.setText(4,0,'Subject: ');
var subject = app.createListBox().setName('subject').setId('subject').addItem('Fundamentals').addItem('Observing').addItem('Solar System').addItem('Stars').addItem('Stellar Evolution').addItem('Milky Way').addItem('Galaxies').addItem('Cosmology')
formContent.setWidget(4,1,subject);
var submitButton = app.createSubmitButton("Submit").setId("submitButton");
formContent.setWidget(5,1,submitButton);
//var handler = app.createServerHandler("pauseUi");
//submitButton.addClickHandler(handler);
form.add(formContent);
app.add(form);
var resultTextArea = app.createTextArea().setName("resultArea").setId("resultArea");
resultTextArea.setVisibleLines(5);
resultTextArea.setSize("80%","80%");
app.add(resultTextArea);
var ogga = 'good god';
Logger.log(ogga);
return app;
}
function pauseUi(e){
var app = UiApp.getActiveApplication();
app.getElementById("file").setEnabled(false);
app.getElementById("fileName").setEnabled(false);
app.getElementById("fileDescription").setEnabled(false);
app.getElementById("submitButton").setEnabled(false);
app.getElementById("level").setEnabled(false);
app.getElementById("subject").setEnabled(false);
app.getElementById("resultArea").setEnabled(false);
app.getElementById("resultArea").setText('Please wait...');
return app;
}
function resetUi(app){
app.getElementById("file").setEnabled(true);
app.getElementById("fileName").setEnabled(true);
app.getElementById("fileDescription").setEnabled(true);
app.getElementById("submitButton").setEnabled(true);
app.getElementById("level").setEnabled(true);
app.getElementById("subject").setEnabled(true);
app.getElementById("resultArea").setEnabled(true);
}
function doPost(e){
var app = UiApp.getActiveApplication();
Logger.log(e.parameter);
//create new page for uploaded file
var msg = createNewPage(e.parameter.fileName,e.parameter.fileUpload,e.parameter.fileDescription,e.parameter.level,e.parameter.subject);
//reset upload page
resetUi(app);
//notify user of success or failure
app.getElementById("resultArea").setText(msg.join('\n'));
return app;
}
function createNewPage(fileName,uploadedFile,fileDescription,level,subject){
//site information
var mysite = SitesApp.getSite("uw.edu","introductory-astronomy-clearinghouse");
var labsPage = mysite.getChildByName("labs-exercises");
Logger.log('url for lab page is: '+labsPage.getUrl());
var msg = [];
//create new page
var page = findPage(fileName);
if (page == null){
var page = labsPage.createFileCabinetPage(fileName, normalizeName(fileName), '');
}
try{
//add file to file cabinet
var attachment = page.addHostedAttachment(uploadedFile);
//see if already listed on list
var listItem = getFileListItem(fileName);
if (listItem == null) {
var fileUrl = page.getUrl();
var newValues = [repairUrlValue(fileUrl, fileName), fileDescription, level, subject];
labsPage.addListItem(newValues);
}
msg.push('Refresh page to see your item added or edit your file at: '+fileUrl);
} catch(e){
msg.push('Failed to upload the '+ fileName +' attachment, possibly due to size constraints or time out issues.');
}
return msg;
}
function getFileListItem(fileName){
var mysite = SitesApp.getSite("uw.edu","introductory-astronomy-clearinghouse");
var labPage = mysite.getChildByName("labs-exercises");
var i = getListItemIndex(labPage,fileName,0);
var items = labPage.getListItems();
Logger.log('labPage list item'+items[i].getValueByIndex(0));
return (i>-1)? labPage.getListItems()[i]:null;
}
//get the index of your item
function getListItemIndex(listPage,propOneValue,propOneIndex){
//for column propOneIndex, returns index (row) that equals propOneValue, or -1.
var listItems = listPage.getListItems();
Logger.log('listItems '+listItems.length);
var r = -1;
for (var i = 0;i<listItems.length && r<0;i++){
if ((listItems[i].getValueByIndex(propOneIndex) == propOneValue)){r = i;}
}
return r;
}
//repairs URL
function repairUrlValue(url,text){
Logger.log('buildAnchor for'+text+'->'+url);
var a = '"'+text+'';
Logger.log('...built '+a);
return a;
}
//find name of page with normalized name
function findPage(name){
var mysite = SitesApp.getSite("uw.edu","introductory-astronomy-clearinghouse");
var parentPage = mysite.getChildByName("labs-exercises");
var norm = normalizeName(name);
var page = parentPage.getChildByName(norm);
Logger.log('findPage '+page.getUrl());
return page;
}
//get size of attached file in KB
function getBlobSize(blob) {
return Math.round(blob.getBytes().length/1024)+" KB";
}
//put the name into reasonable form
function normalizeName(header){
var key = "";
for (var i = 0; i < header.length; ++i){
var letter = header[i];
if (letter == " " && key.length > 0){
key +='-';
continue;
}
if (!isAlnum(letter)){
continue;
}
if (key.length == 0 && isDigit(letter)){
continue; //first character must be a letter
}
key += letter.toLowerCase();
}
Logger.log("normalizeName from '"+header+"' to '"+key+"'");
return key;
}
/*
i s A l n u m
Returns true if the character char is alphabetical, false otherwise
*/
function isAlnum(char){
return char >= 'A' && char <= 'Z' ||
char >='a' && char <= 'z' ||
isDigit(char);
}
/* i s D i g i t
Returns true if the character is a digit, false otherwise.
*/
function isDigit(char){
return char >='0' && char <= '9';
}
Unexpected error occurs, most often, when you try to access a UI element by ID whose ID is not valid.
In your case, there is no widget such as
app.getElementById("file").setEnabled(false);