I'm looking for how to get the file name by the FileUpload just by the file selected before a submit button pushed. But it seems not allowed.
I think the following code can probably hold up the FileUpload changed.
function doGet()
{
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
var fileUploader = app.createFileUpload().setName('thefile');
var handler = app.createServerHandler('fileChangeHandler');
handler.addCallbackElement(panel);
fileUploader.addChangeHandler(handler);
panel.add(fileUploader);
var form = app.createFormPanel();
form.add(panel);
app.add(panel);
return app;
}
But I don't know how to grab the file name in fileChangeHandler(). For example, the following is a failed code:
function fileChangeHandler(e)
{
var app = UiApp.getActiveApplication();
Logger.log(e.parameter.thefile);
return app;
}
Thanks very much for your comments ^^
You cannot use a regular button for FileUpload, you must use a SubmitButton. See these two answers.
GAS: GUI Builder, File Upload, Submit Button
File upload at google apps script
Related
I created one google-form in that google-form i want user to upload their image. so i need a upload button to put their passport size image. i have written an separate code to upload image. where i can upload image the image comes and saved in drive. there are 2 pieces. i want this to merge or combine . i want to include a upload button image in the form and the uploaded image should come and save in the form spreadsheet. thanku
function doGet(e) {
var app = UiApp.createApplication().setTitle("Upload CSV to Sheet");
var form = app.createFormPanel().setId('frm').setEncoding('multipart/form-data');
var formContent = app.createVerticalPanel();
form.add(formContent);
formContent.add(app.createFileUpload().setName('thefile'));
formContent.add(app.createSubmitButton('Submit'));
app.add(form);
return app;
}
function doPost(e) {
// data returned is a blob for FileUpload widget
var fileBlob = e.parameter.thefile;
var doc = DocsList.createFile(fileBlob);
var app = UiApp.getActiveApplication();
//Display a confirmation message
var label = app.createLabel('file uploaded successfully');
app.add(label);
return app;
}
It's not possible to merge this function to a Google form.
I have created a Google Apps script and I have a question about passing a variable to the click handler. The script is published as a Web App and is accessed by an HTML link in an email (its an approve/deny form for a business request). When someone submits a form, an email is sent to the approver who when clicks on the approve link. This link contains the following variables:
?status=enteredInCC&rowNum=9
So when they click on the link the script is launched, and it enters the function doGet(e) block and where relevant code is:
var app = UiApp.createApplication();
var grid = app.createGrid(1, 2);
var label = app.createLabel('Please enter the item\'s PLU:')
var input = app.createTextBox().setId("input").setName("input");
grid.setWidget(0, 0, label);
grid.setWidget(0, 1, input);
var handler = app.createServerHandler("retrieveInput").addCallbackElement(input);
var button = app.createButton("OK", handler);
var panel = app.createVerticalPanel().setId("panel")
panel.add(grid);
panel.add(button);
app.add(panel);
return app;
Which leads to the click handler:
function retrieveInput(e){
var input = e.parameter.input;
var app = UiApp.getActiveApplication();
var panel = app.getElementById('panel');
panel.clear();
app.add(app.createHTML('<h2>The request has been updated. You can close this window.</h2>'))
app.close()
return app;
}
And all of that runs great. However, earlier in the doGet(e) function some information was collected from the URL and stored in variables. Now in retrieveInput(e) I'm needing to access those variables to make some updates to the Spreadsheet (just after panel.clear()). Any ideas?
Storing in variables will not work because the retrieveInput function is called in a new/different "instance" of your script, therefore not being able to access variables set in the doGet. In your case, I suggest you save the desired parameters as hidden inputs in the panel and use it as callbackElement instead of only the input. Like this:
function doGet(e) {
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId("panel")
panel.add(app.createHidden('status', e.parameter.status));
panel.add(app.createHidden('rowNum', e.parameter.rowNum));
var grid = app.createGrid(1, 2);
var label = app.createLabel('Please enter the item\'s PLU:')
var input = app.createTextBox().setId("input").setName("input");
grid.setWidget(0, 0, label);
grid.setWidget(0, 1, input);
var handler = app.createServerHandler("retrieveInput")
.addCallbackElement(panel); //changed to panel instead of input
var button = app.createButton("OK", handler);
panel.add(grid).add(button);
return app.add(panel);
}
Then you can use e.parameter.status and others normally in retrieveInput(e).
Background: I have a google site and I have been pulling information from a google spreadsheet containing the marks of my students, however I'd like to make it more dynamic so that they can request a report of all of their current marks whenever they'd like. In the script that I've written, students will enter a password, click a button and then their marks will be generated.
Issue: From what I've read, when they click the button, the handler for the button causes the script to be re-run. The current spreadsheet cannot be stored and when I try to access the spreadsheet, it tells me that it is null. How can I get access to the spreadsheet again? I've tried using ScriptProperties, but I got the same result. By the way, it works if I do not try to run it as a webapp.
Here's the doGet() function and part of the getPassword() function that is called once the button on the UI is pressed.
function doGet() {
var app = UiApp.createApplication();
app.add(app.loadComponent("MyGui"));
var panel = app.getElementById("VerticalPanel1");
var text = app.createPasswordTextBox().setName("text");
var handler = app.createServerHandler("getResults").addCallbackElement(text);
panel.add(text);
panel.add(app.createButton("Get Record", handler));
SpreadsheetApp.getActiveSpreadsheet().show(app);
}
function getResults(eventInfo) {
var app = UiApp.createApplication();
var password = eventInfo.parameter.text;
var panel = app.getElementById("VerticalPanel1");
var textArea = app.createRichTextArea();
panel.add(textArea);
var pointsSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var passwordCheckRange = pointsSheet.getRange("B70:C94").getValues();
...
The problem probably is that when the script is run as a webapp theres no "activeSpreadSheet"
so
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
fails. An alternate aproach will be to pass the SpreadSheet id in hidden field to the call back.
In your doGet function:
var hidden = app.createHidden('ssId', 'YOUR_SS_ID_HERE');
panel.add(hidden);
var handler = app.createServerHandler("getResults").addCallbackElement(text);
handler.addCallbackElement(hidden)`
In your callback function
var ssID = eventInfo.parameter.ssId;
var pointsSheet = SpreadsheetApp.openById(ssID).getSheetByName('SHEET_NAME');
I am coding a contract application in Google App Script.
It creates a GoogleDoc from a template that include an image of the seller's signature and initials.
As there are five seller, and a dozen different templates, is there a way to change the image of signature and initials?
I have no clues where to start looking for that.
thanks and have a nice day!
Eric
EDIT : I found something about InlineImage in DocumentApp... still looking
Here is a little code which appends a an image in a Google doc. Hope this will give you Idea to get going.
Similar concept I used to make a resume builder application which replaces Profile picture and a signature image
//Make a UI form to upload Image
function doGet() {
var app = UiApp.createApplication();
//Form
var form = app.createFormPanel().setEncoding('multipart/form-data').setId('form');
//Add this form to the application
app.add(form);
//Panel to hold form elements
var panel = app.createVerticalPanel();
//add this panel inside form
form.add(panel);
//Now create form elemnts
var label1 = app.createLabel('Upload Image');
var uploadControl = app.createFileUpload().setName('file').setId('file');
var submitBtn = app.createSubmitButton('Submit');
//Add all these elemnts to the panel
panel.add(label1).add(uploadControl).add(submitBtn);
//Return the application to the service URL
return app;
}
//This function is callend when the form is submitted
function doPost(e){
var fileBlob = e.parameter.file; //This is the image blob if an image is uploded
//Open the document
var doc = DocumentApp.openById('ID OF GOOGLE DOC')//change Id of the document
//get the body of document
var docBody = doc.getActiveSection();
//Append the iamge in document body
docBody.appendImage(fileBlob);
//Save and close the document
doc.saveAndClose();
}
If the title is confusing, hopefully this makes it more clear what I'm trying to do:
function doGet(e) {
var app = UiApp.createApplication();
var list = app.createListBox().setName('list');
list.addItem("this");
list.addItem("that");
list.addItem("they");
var handler = app.createServerHandler('foo').addCallbackElement(list);
list.addChangeHandler(handler);
var label = app.createLabel("test").setId('label');
var panel = app.createVerticalPanel();
panel.add(list);
panel.add(label);
app.add(panel);
return app;
}
function foo(e) {
var app = UiApp.getActiveApplication();
var value = e.parameter.list;
var label = app.getElementById('label');
label.setText(value);
}
It doesn't call any errors. If I intentionally put an error in foo, I get an error message, so I'm assuming the handler is getting called and just isn't doing anything. This works in a spreadsheet if I just have it bring up a Browser.msgBox(value), so I know that much works.
I'm trying to use this in a program that will automatically update all the listboxes on the page based on what is selected in the first listbox. I've been able to change things like visibility using server handlers and app.getElementById, but only with radio buttons, not a list box. I'm clearly doing something wrong here, but it's not obvious what that is.
To have your changes to the UiApp updated you have to return the app on your handler, e.g.
//...
label.setText(value);
return app;
}