I am new to google script. I have a datasource that I need to display in a table and allow user to select a row and select open button. the event handler of the open button should be able to find out the row number so that I will be able to send a request with the name user chosen.
I thought of adding a check box and on the click event, simply read the name of the checkbox which has the row number.
Please let me know how to do this. thanks
var panel = app.createVerticalPanel();
var scroll = app.createScrollPanel().setPixelSize(500, 300);
scroll.add(panel);
var flexTable = app.createFlexTable().setStyleAttribute('border', '1px solid black')
.setStyleAttribute('borderCollapse','collapse')
.setBorderWidth(1);
flexTable.setText(0, 1, 'Application Name')
flexTable.setRowStyleAttribute(0,'color', 'blue')
flexTable.setText(0, 2, 'Owner')
flexTable.setText(0, 3, 'Date')
var handler = app.createServerClickHandler('clickTable');
var counter = 1;
for (var i in queryResult.records) {
var chkBox = app.createCheckBox().setName('chk' + counter).setId('chk');
var owner = queryResult.records[i]["Owner"]["Name"];
var AppName = queryResult.records[i]["Name"];
var ModifiedDate = queryResult.records[i]["LastModifiedDate"]
var UniqId = queryResult.records[i]["Apttus_XApps__UniqueId__c"]
flexTable.setWidget(counter, 0 , chkBox)
flexTable.setText(counter, 1, AppName.toString());
flexTable.setText(counter, 2, owner.toString());
flexTable.setText(counter, 3, ModifiedDate.toString());
counter ++;
}
panel.add(app.createButton('Open', handler));
panel.add(flexTable);
app.add(scroll);
You have only created server handler, but no callback elements are attached to it. Please have a look at this page
So your code will be like.
var handler = app.createServerClickHandler('clickTable');
handler.addCallbackElement(panel)
Next: at your server function clickTable
function clickTable(e)
{
for (var i in e.parameter) {
Logger.log('parameter ' + i+1 + ' is ' + e.parameter[i]);
}
//try logging all the values that are passed and use it accordingly,
}
Here is an example of an implementation I suggested in comments above using radioButtons.
User can only submit if one option has been selected
test online here
code :
function doGet(){
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setStyleAttributes({'padding':'15px'});
var handler = app.createServerClickHandler('clickTable').addCallbackElement(panel);
var btn = app.createButton('Open', handler).setEnabled(false);
panel.add(btn);
var scroll = app.createScrollPanel().setPixelSize(500, 400);
scroll.add(panel);
var flexTable = app.createFlexTable().setStyleAttribute('border', '1px solid black')
.setStyleAttributes({'borderCollapse':'collapse'})
.setBorderWidth(1).setCellPadding(2);
flexTable.setText(0, 1, 'Application Name')
flexTable.setRowStyleAttribute(0,'color', 'blue')
flexTable.setText(0, 2, 'Owner')
flexTable.setText(0, 3, 'Date')
var radioValue = app.createTextBox().setName('radioValue').setVisible(false);// set it to visible if you want to see what happens in tests
panel.add(radioValue);
var counter = 1;
for (var i =0;i<10;i++) {
var name = counter;
var radio = app.createRadioButton('radioBtn','select');
var CliHandler = app.createClientHandler().forTargets(radioValue).setText(name).forTargets(btn).setEnabled(true);
radio.addClickHandler(CliHandler);
// var owner = queryResult.records[i]["Owner"]["Name"];
// var AppName = queryResult.records[i]["Name"];
// var ModifiedDate = queryResult.records[i]["LastModifiedDate"]
// var UniqId = queryResult.records[i]["Apttus_XApps__UniqueId__c"]
// temp var definitions for test
var owner = 'test';
var AppName = 'test';
var ModifiedDate = 'test';
var UniqId = 'test';
// delete in production code
flexTable.setWidget(counter, 0 , radio)
flexTable.setText(counter, 1, AppName.toString());
flexTable.setText(counter, 2, owner.toString());
flexTable.setText(counter, 3, ModifiedDate.toString());
counter ++;
}
panel.add(flexTable);
app.add(scroll);
return app;
}
function clickTable(e){
var app = UiApp.getActiveApplication();
app.add(app.createLabel('you have selected item nr '+e.parameter.radioValue));
return app
}
Related
I am trying to update my code to work with the new DriveApp API update. I got most of it working (I think) but it is hanging up on line 68 saying that it can't getFilesByType. I did try and change the loop for adding to be based off the iterator (I think) but still get this error: TypeError: Cannot find function getFilesByType in object FolderIterator
Any help would be appreciated thanks!
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
Template Generator By: Andre Fecteau - klutch2013#gmail.com
Original Code From: kiszal#gmail.com (Found in the template gallery by searching "Templates" It is the first One.
Major Help from: Serge Insas On Stack Overflow (He did most of the work.)
Link 1: http://stackoverflow.com/questions/18147798/e-undefined-google-script-error
Link 2: http://stackoverflow.com/questions/18132837/have-a-listbox-populate-with-every-folder-in-mydrive
How To Use:
First: each column is designated in your Template by {Column Letter} for example for column A it would be {A}
Second: You can change this, but your Template must be in a folder called "Templates." This folder can be anywhere in your drive.
Third: Click "Generate Documents Here!" Then click "Export Row to Document"
Fourth: Type in the row you want to export. Chose your Folder Path. Click Submit.
NOTE ON FOURTH STEP: If you want your number to skip the header row add a +1 to line 32.
This would mean if you typed "2" in the row box it actually exports row 3. I took this out because it can get confusing at times.
NOTE: Line 71 you can edit the word "Templates" to whatever folder you saved your Template into.
NOTE: Line 36 you can edit to change what comes up in the name of the file that is created. To do this just edit the column letter in the following piece: "+Sheet.getRange('E'+row).getValue()+"
You can then delete any other columns you do not want by deleteing the section of code that looks like the following: '+Sheet.getRange('D'+row).getValue()+'
Feel free to edit this code as you wish and for your needs. That is what I did with the original code.
So there is no reason I should restrict what others do with this code.
Bug Fix Log:
* changed row: 32 to remove the +1 6/18/2014
* changed row: 40 to remov e the row-- 6/18/2014
* changed row: 68 to update to DriveApp because of Google API Update - 4/21/15
* changed row: 68 to update to getFoldersByName and getFilesByType to update to new Google API - 4/21/15
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function generateDocument(e) {
var template = DriveApp.getFileById(e.parameter.Templates);
Logger.log(template.getName());
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var row = Number(e.parameter.row) //+1; // Remove the // in this line next to the +1 to skip headers
Logger.log(row);
var currentFID = e.parameter.curFID;
Logger.log(currentFID);
var myDocID = template.makeCopy(Sheet.getRange('B' + row).getValue() + ' - ' + Sheet.getRange('E' + row).getValue() + ' - ' + Sheet.getRange('D' + row).getValue() + ' - ' + Sheet.getRange('X' + row).getValue()).getId();
var myDoc = DocumentApp.openById(myDocID);
var copyBody = myDoc.getActiveSection();
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
//row--; // decrement row number to be in concordance with real row numbers in sheet
var myRow = SpreadsheetApp.getActiveSpreadsheet().getRange(row + ":" + row);
for (var i = 1; i < Sheet.getLastColumn() + 1; i++) {
var myCell = myRow.getCell(1, i);
copyBody.replaceText("{" + myCell.getA1Notation().replace(row, "") + "}", myCell.getValue());
}
myDoc.saveAndClose();
var destFolder = DriveApp.getFolderById(currentFID);
Logger.log(myDocID);
var doc = DriveApp.getFileById(myDocID); // get the document again but using DriveApp this time...
doc.addToFolder(destFolder); // add it to the desired folder
doc.removeFromFolder(DriveApp.getRootFolder()); // I did it step by step to be more easy to follow
var pdf = DriveApp.getFileById(myDocID).getAs("application/pdf");
destFolder.createFile(pdf); // this will create the pdf file in your folder
var app = UiApp.getActiveApplication();
app.close();
return app;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function getTemplates() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setTitle('Generate from template');
// Create a grid with 3 text boxes and corresponding labels
var grid = app.createGrid(5, 2);
grid.setWidget(0, 0, app.createLabel('Template name:'));
var list = app.createListBox();
list.setName('Templates');
grid.setWidget(0, 1, list);
var docs = DriveApp.getFoldersByName("Templates").getFilesByType(documents); //Change the word "Templates" to whatever folder you saved your template into
/* OLD LOOP
for (var i = 0; i < docs.length; i++) {
list.addItem(docs[i].getName(),docs[i].getId());
}
*/
while (docs.hasNext()) {
var docs = docs.next();
list.addItem(docs[i].getName(), docs[i].getId());
}
grid.setWidget(1, 0, app.createLabel('Row:'));
var row = app.createTextBox().setName('row');
row.setValue(SpreadsheetApp.getActiveSpreadsheet().getActiveRange().getRow());
grid.setWidget(1, 1, row);
var curFN = app.createTextBox().setText('MyDrive/').setName('curFN').setId('curFN').setWidth('400');
var curFID = app.createTextBox().setText(DriveApp.getRootFolder().getId()).setName('curFID').setId('curFID').setVisible(false);
var listF = app.createListBox().setName('listF').setId('listF').addItem('Please Select Folder', 'x');
grid.setText(2, 0, 'Type Path:').setWidget(2, 1, curFN).setText(3, 0, 'OR').setText(4, 0, 'Choose Path:').setWidget(4, 1, listF).setWidget(3, 1, curFID);
var folders = DriveApp.getRootFolder().getFolders();
for (var i = 0; i < folders.length; i++) {
listF.addItem(folders[i].getName(), folders[i].getId())
}
var handlerF = app.createServerHandler('folderSelect').addCallbackElement(grid);
listF.addChangeHandler(handlerF);
var panel = app.createVerticalPanel();
panel.add(grid);
var button = app.createButton('Submit');
var handler = app.createServerClickHandler('generateDocument');
handler.addCallbackElement(grid);
button.addClickHandler(handler);
// Add the button to the panel and the panel to the application, then display the application app in the Spreadsheet doc
panel.add(button);
app.add(panel);
doc.show(app);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function folderSelect(e) {
var app = UiApp.getActiveApplication();
var currentFN = e.parameter.curFN;
var currentFID = e.parameter.listF;
Logger.log(currentFID);
var listF = app.getElementById('listF');
var curFN = app.getElementById('curFN');
var curFID = app.getElementById('curFID');
if (currentFID == 'x') {
currentFID = DriveApp.getRootFolder().getId();
curFN.setText('MyDrive/')
};
var startFolder = DriveApp.getFolderById(currentFID);
var folders = startFolder.getFolders();
listF.clear().addItem('No More Sub Folders!', 'x').addItem('Go back to Root', 'x');
if (folders.length > 0) {
listF.clear();
listF.addItem('Select Sub Folder', 'x')
};
for (var i = 0; i < folders.length; i++) {
listF.addItem(folders[i].getName(), folders[i].getId())
}
curFN.setText(currentFN + DriveApp.getFolderById(currentFID).getName() + '/');
if (currentFID == DriveApp.getRootFolder().getId()) {
curFN.setText('MyDrive/')
};
curFID.setText(currentFID);
return app;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{
name: "Export Row to Document",
functionName: "getTemplates"
}];
ss.addMenu("Generate Documents Here!", menuEntries);
}
You need two while loops:
var folders = DriveApp.getFoldersByName("Templates");
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
var allMyFilesByType = folder.getFilesByType(mimeType)
};
while (allMyFilesByType.hasNext()) {
var file = allMyFilesByType.next();
Logger.log(file.getName());
};
For MIME Types, see:
Google Documentation - MIME Types
I'm trying to make a script to put on my google site for my students so that they can look up their login details for mymaths from home. I have a spreadsheet with all their emails which match up to their login details but when they access the page I want the to be able to just see their row. I am using Session.getActiveUser().getEmail() for this and all of my code is below but it is not working!
Any help would be greatly appreciated.
var userID = Session.getActiveUser().getEmail();
var userLogin;
var userPass;
var userName;
var text;
//Function to lookup login and password from email and add to variables
function lookup() {
var spreadsheetKey = '1UftMLEgJPof3533X1Dp2IRqLIJa-70y8m-xnbyfj8ZA';
var sheet = SpreadsheetApp.openById(spreadsheetKey);
var end = SpreadsheetApp.getActiveSheet().getLastRow();
var range = sheet.getRange(1, 0, end, 4);
var values = range.getValues();
for (i = 0; i < values.length; ++i) {
if (values[i][0] == userID) {
text = 'Here are your login details for MyMaths. Now get on with your homework!'
userName = string(values[i][1]);
userLogin = string(values[i][2]);
userPass = string(values[i][3]);
}
else {
text = 'Sorry, but there is an error. You will need to check in your book or ask your teacher for your MyMaths login details.'
}
}
}
//Function to create Userinterface on site page
function doGet() {
var app = UiApp.createApplication();
var panel = app.createAbsolutePanel();
var label = app.createLabel(text);
var table = app.createGrid(2,3);
table.setText(0, 0, 'Name');
table.setText(0, 1, 'Login');
table.setText(0, 2, 'Password');
table.setText(1, 0, userName);
table.setText(1, 1, userLogin);
table.setText(1, 2, userPass);
panel.add(label);
panel.add(table);
app.add(panel);
return app;
}
The way you implemented this is not going to work. You defined a number of variables as "global" so that each function could use it but although this is true, the functions won't be able to modify them..., in other words : they cannot assign a value to these variables.
I would suggest to build this in a completely different way : a main doGet that would call a lookup function, this latter returning the appropriate values (as an array or an object).
The code goes like this, I didn't test it because I didn't have data to do so but it should work as expected.
btw, think about using some styles to make it look nicer :-) see this post from Anees Hameed showing a smart way to do it.
//Function to create Userinterface on site page
function doGet() {
var userID = Session.getEffectiveUser().getEmail();
var result = lookup(userID);
var app = UiApp.createApplication();
var panel = app.createAbsolutePanel();
var label = app.createLabel(result.text);
var table = app.createGrid(2,3);
table.setText(0, 0, 'Name');
table.setText(0, 1, 'Login');
table.setText(0, 2, 'Password');
table.setText(1, 0, result.userName);
table.setText(1, 1, result.userLogin);
table.setText(1, 2, result.userPass);
panel.add(label);
panel.add(table);
app.add(panel);
return app;
}
function lookup(userID) {
var result = {};
var spreadsheetKey = '1UftMLEgJPof3533X1Dp2IRqLIJa-70y8m-xnbyfj8ZA';
var sheet = SpreadsheetApp.openById(spreadsheetKey);
var end = SpreadsheetApp.getActiveSheet().getLastRow();
var range = sheet.getRange(1, 0, end, 4);
var values = range.getValues();
for (i = 0; i < values.length; ++i) {
if (values[i][0] == userID) {
result['text'] = 'Here are your login details for MyMaths. Now get on with your homework!'
result['userName'] = string(values[i][1]);
result['userLogin'] = string(values[i][2]);
result['userPass'] = string(values[i][3]);
}
else {
result['text'] = 'Sorry, but there is an error. You will need to check in your book or ask your teacher for your MyMaths login details.'
result['userName'] = '-';
result['userLogin'] = '-';
result['userPass'] = '-';
}
}
return result;
}
I'm working on an answer for another question found here. I have modified a different tutorial script from here, but I'm having an issue that the e.parameter for the fileUploadWidget will not accept a .setName() change. No matter what I do with setName, it continues to show the "name" as FileUpload, and won't pass the e.parameter.'file'+numRows on to the uploadFiles(e) (formerly doPost(e)). The folderName parameter will come through, but numRows is coming through as NaN, and the file+numRows is coming through undefined. What is going on here/What am I missing? I've been through tons of solutions on and off SO, but can't seem to figure out where this has gone wrong. Maybe a fresh set of eyes with more experience can see what I'm doing wrong.
You can find the example of this code in action here
//modified from script found here http://www.googleappsscript.org/miscellaneous/creating-form-elements-dynamically-using-google-apps-script-gas
function doGet() {
var app = UiApp.createApplication();
var panel = app.createVerticalPanel();
var formPanel = app.createFormPanel();
var folderLabel = app.createLabel('Folder Name (temp placeholder to remember to use .getFolderById(folderId) to place in specific folder)');
var folderNameTextBox = app.createTextBox().setId('folderName').setName('folderName');
var filesLabel = app.createLabel('Add Files to Upload');
var table = app.createFlexTable().setId('table').setTag('0'); //Here tag will count the number of members
//Write the header for the table
var headerArray = ['File(s)'];
for(var i=0; i<headerArray.length; i++){
table.setWidget(0, i, app.createLabel(headerArray[i]));
}
//Add the first row of form elelments to input Member information
addMemebrRow(app);
//Add a button to submit the info
var button = app.createSubmitButton('Upload File(s)');
var handler = app.createServerHandler('uploadFiles');
handler.addCallbackElement(panel);
button.addClickHandler(handler);
panel.add(folderLabel)
.add(folderNameTextBox)
.add(filesLabel)
.add(table)
.add(button);
formPanel.add(panel);
app.add(formPanel);
return app;
}
function addMemebrRow(app){
var table = app.getElementById('table');
var tag = parseInt(table.getTag());
Logger.log(tag);
var numRows = tag+1;
if(numRows >1){
table.removeCell(numRows-1, 5);
table.removeCell(numRows-1, 4);
}
Logger.log(numRows);
var uploadWidget = app.createFileUpload();
var uploadWidgetName = uploadWidget.setName('file'+numRows);
var uploadWidgetId = uploadWidget.setId('file'+numRows);
Logger.log(uploadWidgetId.getId());
Logger.log(uploadWidgetName);
table.setWidget(numRows, 0, uploadWidget);
table.setTag(numRows.toString());
addButtons(app);
}
function addButtons(app){
var table = app.getElementById('table');
var numRows = parseInt(table.getTag());
//Create handler to add/remove row
var addRemoveRowHandler = app.createServerHandler('_addRemoveRow');
addRemoveRowHandler.addCallbackElement(table);
//Add row button and handler
var addRowBtn = app.createButton('+').setId('addOne').setTitle('Add row');
table.setWidget(numRows, 4, addRowBtn);
addRowBtn.addMouseUpHandler(addRemoveRowHandler);
//remove row button and handler
var removeRowBtn = app.createButton('-').setId('removeOne').setTitle('Remove row');
table.setWidget(numRows, 5, removeRowBtn);
removeRowBtn.addMouseUpHandler(addRemoveRowHandler);
}
function _addRemoveRow(e){
Logger.log(e.parameter.source);
var app = UiApp.getActiveApplication();
var table = app.getElementById('table');
var tag = parseInt(e.parameter.table_tag);
var source = e.parameter.source;
//Logger.log(tag);
if(source == 'addOne'){
table.setTag(tag.toString());
addMemebrRow(app);
}
else if(source == 'removeOne'){
if(tag > 1){
//Dcrement the tag by one
var numRows = tag-1;
table.removeRow(tag);
//Set the new tag of the table
table.setTag(numRows.toString());
//Add buttons in previous row
addButtons(app);
}
}
return app;
}
function uploadFiles(e) {
var foldername = e.parameter.folderName;
Logger.log(foldername);
var numFiles = parseInt(e.parameter.table_tag);
Logger.log(numFiles);
for (var i = 1; i<=numFiles; i++){
Logger.log(i);
var fileBlob = e.parameter['file'+i];
var newFile = DocsList.getFolderById("0B2p9JhtmHqC8Q0lIQk1mMERQTW8").createFile(fileBlob);
}
var app = UiApp.getActiveApplication();
var label = app.createLabel(numFiles +' file(s) uploaded successfully');
app.add(label);
return app;
}
File upload in forms needs a doPost function to work, this is not an option ;)
In such a structure (doGet/doPost) you don't have to define a handler nor a callBackElement, the formPanel is supposed to include all its elements automatically.
So I tried your modified code and still get one major issue with the numFiles value that is on the table tag : I can't get it...
If I replace it with a fixed value then everything works nicely, I get the files in the right folder.
So this answer is not a good answer because it doesn't bring a full solution but at least it reduces its initial scope to that point : how to get this ##!#! numFiles value ?
EDIT : Found the issue : table doesn't support setName method so its value can't be retrieved in the submitHandler. We should use another widget to hold that value.
new working Code below : (I used a textBox as a "hidden" widget for test only, please replace by a hiddenWidget when in production)
function doGet() {
var app = UiApp.createApplication();
var panel = app.createVerticalPanel();
var formPanel = app.createFormPanel();
var folderLabel = app.createLabel('Folder Name (temp placeholder to remember to use .getFolderById(folderId) to place in specific folder)');
var folderNameTextBox = app.createTextBox().setId('folderName').setName('folderName');
var filesLabel = app.createLabel('Add Files to Upload');
var table = app.createFlexTable().setId('table').setTag('0'); //Here tag will count the number of members
//Write the header for the table
var headerArray = ['File(s)'];
for(var i=0; i<headerArray.length; i++){
table.setWidget(0, i, app.createLabel(headerArray[i]));
}
//Add the first row of form elelments to input Member information
addMemebrRow(app);
var hidden = app.createTextBox().setName('hidden').setId('hidden').setValue(table.getTag());// used to hold the number of files, replace with createHidden()
//Add a button to submit the info
var button = app.createSubmitButton('Upload File(s)');
panel.add(folderLabel)
.add(folderNameTextBox)
.add(filesLabel)
.add(table)
.add(button);
formPanel.add(panel.add(hidden));
app.add(formPanel);
return app;
}
function addMemebrRow(app){
var table = app.getElementById('table');
var tag = Number(table.getTag());
Logger.log('tag='+tag);
var numRows = tag+1;
if(numRows >1){
table.removeCell(numRows-1, 5);
table.removeCell(numRows-1, 4);
}
Logger.log(numRows);
var uploadWidget = app.createFileUpload();
var uploadWidgetName = uploadWidget.setName('file'+numRows);
var uploadWidgetId = uploadWidget.setId('file'+numRows);
Logger.log(uploadWidgetId.getId());
Logger.log(uploadWidgetName);
table.setWidget(numRows, 0, uploadWidget);
table.setTag(numRows);
addButtons(app);
}
function addButtons(app){
var table = app.getElementById('table');
var numRows = Number(table.getTag());
//Create handler to add/remove row
var addRemoveRowHandler = app.createServerHandler('_addRemoveRow');
addRemoveRowHandler.addCallbackElement(table);
//Add row button and handler
var addRowBtn = app.createButton('+').setId('addOne').setTitle('Add row');
table.setWidget(numRows, 4, addRowBtn);
addRowBtn.addMouseUpHandler(addRemoveRowHandler);
//remove row button and handler
var removeRowBtn = app.createButton('-').setId('removeOne').setTitle('Remove row');
table.setWidget(numRows, 5, removeRowBtn);
removeRowBtn.addMouseUpHandler(addRemoveRowHandler);
}
function _addRemoveRow(e){
Logger.log(e.parameter.source);
var app = UiApp.getActiveApplication();
var hidden = app.getElementById('hidden');
var table = app.getElementById('table');
var tag = Number(e.parameter.table_tag);
var source = e.parameter.source;
//Logger.log(tag);
if(source == 'addOne'){
table.setTag(tag.toString());
hidden.setValue(tag+1);
addMemebrRow(app);
}
else if(source == 'removeOne'){
if(tag > 1){
//Dcrement the tag by one
var numRows = tag-1;
table.removeRow(tag);
//Set the new tag of the table
table.setTag(numRows);
hidden.setValue(numRows);
//Add buttons in previous row
addButtons(app);
}
}
return app;
}
function doPost(e) {
var foldername = e.parameter.folderName;
Logger.log('foldername = '+foldername);
var numFiles = Number(e.parameter.hidden);
Logger.log('numFiles = '+numFiles);
for (var i = 1; i<=numFiles; i++){
Logger.log(i);
var fileBlob = e.parameter['file'+i];
var newFile = DocsList.getFolderById("0B3qSFd3iikE3QXdubnVoMXlGMkk").createFile(fileBlob);
}
var app = UiApp.getActiveApplication();
var label = app.createLabel(numFiles +' file(s) uploaded successfully');
app.add(label);
return app;
}
So I have an app script gadget embedded in a google site. What the app script does is get objects from scriptdb and display it on the screen. There also is an add button clicking on which you get a form to enter information and add objects. What I am trying to do is that after an object is saved, I repopulate the object and display them so the newly created object can be seen without manually refreshing the page.
I have a function called update() that is called after an object is saved and this function takes care of the "auto refresh".
In the save() function, I call the update function with this syntax, update(). Here is the submit() function
function SaveAssignment(e){
var db = ScriptDb.getMyDb();
var app = UiApp.getActiveApplication();
var name = e.parameter.assignmentname;
var date = e.parameter.assignmentdate.toString();
var desc = e.parameter.assignmentdesc;
var category = e.parameter.assignmentcategory;
var totalscore = e.parameter.assignmenttotalscore;
var site = SitesApp.getActiveSite();
var assignment = { name: name,
date: date,
description: desc,
url: pageUrl + '?name='+name+'&date='+date+'&description='+desc+'&id='+sheetId,
sheetid: sheetId,
totalScore: totalscore,
Category: category
};
db.save(assignment);
update();
}
and here is my update() method
function update(){
var app = UiApp.createApplication();
var oldGrid = app.getElementById('grid');
app.remove(oldGrid);
var handler = app.createServerHandler('AddAssignment');
var addAssignmentButton = app.createButton('Add Assignment', handler);
var assignments = db.query({});
var i = 1;
var j = 1;
var grid;
if(assignments.getSize() < 1){
grid = app.createGrid(3, 5).setId('grid');
}
else{
grid = app.createGrid(assignments.getSize() + assignments.getSize() + assignments.getSize(), 5).setId('grid');
}
handler.addCallbackElement(grid);
grid.setWidget(0, 2, addAssignmentButton);
while(assignments.hasNext()){
var assignment = assignments.next();
var name = assignment.name;
var date = assignment.date;
var description = assignment.description;
var nameLabel = app.createLabel('Assignment ' + i + ' : ' + name).setVisible(true);
var dateLabel = app.createLabel('Date: ' + date).setVisible(true);
var idLabel = app.createLabel(assignment.getId()).setVisible(false);
var deletebutton = app.createButton('Delete Assignment');
var handler = app.createServerHandler('deleteAssignment');
handler.addCallbackElement(idLabel);
deletebutton.addClickHandler(handler);
grid.setWidget(j, 0, nameLabel);
j = j + 1;
grid.setWidget(j, 0, dateLabel);
grid.setWidget(j, 1, deletebutton);
grid.setWidget(j, 3, idLabel);
i++;
j = j + 2;
}
app.add(grid);
return app;
I made some little test on your code. you need to do some little changes:
You need to change "var app = UiApp.createApplication();" for "var app = UiApp.getActiveApplication()" (already saw that in comment).
You didn't declared "db" your script will systematically be in error if you don't correct that.
Bellow your code where the update function actually update the grid:
function doGet(){
var app = UiApp.createApplication();
var grid = app.createGrid(3, 3).setId("grid").setWidget(1, 2, app.createLabel("test"));
grid.addClickHandler(app.createServerHandler("update"));
app.add(grid);
return(app);
}
function update(){
var app = UiApp.getActiveApplication(); // getActiveApplication
var oldGrid = app.getElementById('grid');
app.remove(oldGrid);
var handler = app.createServerHandler('AddAssignment');
var addAssignmentButton = app.createButton('Add Assignment', handler);
var db = ScriptDb.getMyDb();
var assignments = db.query({}); // YOU DIDNT DECLARED db
var i = 1;
var j = 1;
var grid;
if(assignments.getSize() < 1){
grid = app.createGrid(3, 5).setId('grid');
}
else{
grid = app.createGrid(assignments.getSize() + assignments.getSize() + assignments.getSize(), 5).setId('grid'); // assignments.getSize()*3
}
handler.addCallbackElement(grid);
grid.setWidget(0, 2, addAssignmentButton);
while(assignments.hasNext()){
var assignment = assignments.next();
var name = assignment.name;
var date = assignment.date;
var description = assignment.description;
var nameLabel = app.createLabel('Assignment ' + i + ' : ' + name).setVisible(true);
var dateLabel = app.createLabel('Date: ' + date).setVisible(true);
var idLabel = app.createLabel(assignment.getId()).setVisible(false);
var deletebutton = app.createButton('Delete Assignment');
var handler = app.createServerHandler('deleteAssignment');
handler.addCallbackElement(idLabel);
deletebutton.addClickHandler(handler);
grid.setWidget(j, 0, nameLabel);
j = j + 1;
grid.setWidget(j, 0, dateLabel);
grid.setWidget(j, 1, deletebutton);
grid.setWidget(j, 3, idLabel);
i++;
j = j + 2;
}
app.add(grid);
return app;
}
I am trying to replace some part of a formula in cell D3 of a spreadsheet, but I can't seem to do it. The formula in D3 is very long, but I only need to replace what would be searchtext variable and replace it with replacetext variable. Any ideas? Here's my code.
function dashboards(){
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var origSheet1 = ss1.getSheetByName('Daily');
var searchtext = Browser.inputBox("Enter search text");
var replacetext = Browser.inputBox("Enter replace text");
var form = origSheet1.getRange("D3").getFormulaR1C1();
form.indexof(searchtext);
var updated = form.replace(searchtext, replacetext);
form.setFormula(updated);}
You're not far off. The problem is that form, the below, is a String, not a reference to your Range.
var form = origSheet1.getRange("D3").getFormulaR1C1();
You can see this by inserting
Logger.log(form + "; type: " + typeof form); //String
after that line and checking the log in the Script Editor.
You just need to change
form.setFormula(updated);
to
origSheet1.getRange("D3").setFormulaR1C1(updated);
to update the actual range.
Copy the code below and run it via Script Manager or a menu item.
It operates on whatever the selected range is, whether it's a single cell or extends over multiple rows & columns.
It pops up a toast message to tell you when the procedure has finished but it leaves the UiInstance open in case you want to do more replacing.
You can keep it open and perform multiple search/replace in formulas on multiple selections or the same search on different sheets.
function handySRF() { // script composed by ailish#ahrosters.com
var ss = SpreadsheetApp.getActive();
var app = UiApp.createApplication().setHeight(200).setWidth(270).setTitle('Search and Replace In Formulas');
var panel = app.createAbsolutePanel().setId('panel').setHeight(198).setWidth(268)
.setStyleAttribute('background', 'lightCyan');
var lblSearch = app.createLabel('Search for:').setId('lblSearch');
var txtSearch = app.createTextBox().setId('txtSearch').setName('txtSearch');
var lblReplace = app.createLabel('Replace with:').setId('lblReplace');
var txtReplace = app.createTextBox().setId('txtReplace').setName('txtReplace');
var handler = app.createServerHandler('btnStartSearch');
var btnStartSearch = app.createButton('Start Search').addClickHandler(handler)
.setStyleAttribute('background', 'lightGreen');
handler.addCallbackElement(panel);
var handler2 = app.createServerHandler('btnCloseWindow');
var btnCloseWindow = app.createButton('Close Window').addClickHandler(handler2)
.setStyleAttribute('background', 'lightYellow');
handler2.addCallbackElement(panel);
panel.add(lblSearch, 10, 6)
panel.add(txtSearch, 10, 33)
panel.add(lblReplace, 10, 75)
panel.add(txtReplace, 10, 100)
panel.add(btnStartSearch, 10, 151)
panel.add(btnCloseWindow, 130, 151)
app.add(panel);
ss.show(app);
};
function btnStartSearch(e) {
var ss = SpreadsheetApp.getActive();
var app = UiApp.getActiveApplication();
var search = e.parameter.txtSearch;
var replace = e.parameter.txtReplace;
var rows = ss.getActiveSelection();
var numRows = rows.getNumRows();
var formulas = rows.getFormulas();
var newFormulas = [];
for (var i = 0; i <= numRows - 1; i++) {
var oldData = formulas[i];
var newData = [];
for (var j=0; j<oldData.length; ++j) {
var item = oldData[j].replace(new RegExp(search, "g"), replace);
newData.push(item);
}
newFormulas.push(newData);
}
rows.setFormulas(newFormulas);
var str = 'Finished replacing ' + search + ' with ' + replace;
ss.toast(str, '', 2);
};
function btnCloseWindow(e) {
var ss = SpreadsheetApp.getActive();
var app = UiApp.getActiveApplication();
app.close();
return app;
};