Create Array of Images - google-apps-script

I want to create an array of images using createImage() that reads the URLs from a Google Spreadsheet. I want to ignore empty cell values in the Range and also be able to read values on the adjacent column of the URL. Example: URL, Name, Attribute.
This is what I have so far but cannot get multiple values in the URL range to load into the different image spaces.
function doGet(e) {
var app= UiApp.createApplication().setTitle('Not Here')
var abspanel= app.createAbsolutePanel();//.setHeight('100%').setWidth('100%');
var stackpanel=app.createStackPanel();
var grid = app.createGrid(8,8);
var titleLabel= app.createLabel('Not Here');
titleLabel.setStyleAttribute("text-align", "center");
titleLabel.setStyleAttribute("font-size", "135%");
titleLabel.setStyleAttribute("font-weight", "bold");
var insertlabel= app.createLabel('Which Schedule? (Insert Document Key)');
var inserttxtbox=app.createTextBox().setId('txtbox').setName('ttbox').setMaxLength(44);
var loadbtn= app.createButton('Load Pictures').setId('loadbtn');
var resetbtn= app.createButton('Refresh').setId('rbtn').setVisible(false);
var daylabel= app.createLabel('Select Day');
var mon= "P - Mon"
var tues= "P - Tues"
var wed= "P - Wed"
var thurs= "P - Thurs"
var fri= "P - Fri"
var dayListBox= app.createListBox().setWidth('140px').setId('day').setName ('sday')
dayListBox.addItem(mon);
dayListBox.addItem(tues);
dayListBox.addItem(wed);
dayListBox.addItem(thurs);
dayListBox.addItem(fri);
var image1= app.createImage().setPixelSize(250,250).setId('image1').setVisible(false);
var image2=app.createImage().setPixelSize(250,250).setId('image2').setVisible(false);
var image3=app.createImage().setPixelSize(250,250).setId('image3').setVisible(false);
var image4=app.createImage().setPixelSize(250,250).setId('image4').setVisible(false);
var image5=app.createImage().setPixelSize(250,250).setId('image5').setVisible(false);
var image6=app.createImage().setPixelSize(250,250).setId('image6').setVisible(false);
var loadhandler=app.createServerHandler('loadPics');
loadhandler.addCallbackElement(stackpanel);
loadbtn.addClickHandler(loadhandler);
grid
.setWidget(1,0,insertlabel)
.setWidget(1,1,inserttxtbox)
.setWidget(2,0, daylabel)
.setWidget(2,1, dayListBox)
.setWidget(3,1, loadbtn)
.setWidget(3,2,resetbtn)
.setWidget(4,2,spinner)
.setWidget(5,1, image1)
.setWidget(5,2, image2)
.setWidget(5,3, image3)
.setWidget(6,1, image4)
.setWidget(6,2, image5)
.setWidget(6,3, image6);
abspanel.add(titleLabel);
stackpanel.add(grid);
app.add(abspanel);
app.add(stackpanel);
return app;
}
function loadPics(e){
var app= UiApp.getActiveApplication();
var ss= SpreadsheetApp.openById(e.parameter.ttbox);
var list=ss.getSheetByName(e.parameter.sday);
var row= list.getLastRow()-1;
var values2= list.getRange(2,47,1,1);
var values3= list.getRange(2,48,1,1);
var values4=list.getRange(row,49,1,1).getValues();
var image1=app.getElementById('image1').setVisible(true);
var image2=app.getElementById('image2').setVisible(true);
values4 = values4.split(',');
for(var i=0;i<values4.length;i++){
if (values4[i][0] != '')
image1.setUrl(values4[i]);
}
values4=values4.split(',');
for(var i=0;i<values4.length;i++){
if (values4[i][0] != '')
image2.setUrl(values4[i]);
}
return app;
}

This version loads all the images as you wish. You'll need to adjust the spreadsheet access to suit you - see the embedded comments.
The images are created as an array, so that they can be populated and added to the grid within a loop. Image IDs are likewise created on the fly, and thus loadPics() can follow a similar pattern. An example of adding the value from the "Name" column as the image title is included.
Edit / Added Bonus: Working spinner, and support for Name & Attributes with pictures.
maxImgs = 6; // Number of images in grid
colUrl = 0; // Column containing URL
colName = 1; // Column containing Name
colAttr = 2; // Column containing Attributes
function doGet(e) {
var app = UiApp.createApplication().setTitle('Not Here');
var abspanel = app.createAbsolutePanel(); //.setHeight('100%').setWidth('100%');
var stackpanel = app.createStackPanel();
var grid = app.createGrid(8, 8);
var titleLabel = app.createLabel('Not Here');
titleLabel.setStyleAttribute("text-align", "center");
titleLabel.setStyleAttribute("font-size", "135%");
titleLabel.setStyleAttribute("font-weight", "bold");
var insertlabel = app.createLabel('Which Schedule? (Insert Document Key)');
var inserttxtbox = app.createTextBox().setId('txtbox').setName('ttbox').setMaxLength(44);
var loadbtn = app.createButton('Load Pictures').setId('loadbtn');
var resetbtn = app.createButton('Refresh').setId('rbtn').setVisible(false);
var daylabel = app.createLabel('Select Day');
var mon = "P - Mon"
var tues = "P - Tues"
var wed = "P - Wed"
var thurs = "P - Thurs"
var fri = "P - Fri"
var dayListBox = app.createListBox().setWidth('140px').setId('day').setName('sday')
dayListBox.addItem(mon);
dayListBox.addItem(tues);
dayListBox.addItem(wed);
dayListBox.addItem(thurs);
dayListBox.addItem(fri);
// Borrowed from https://sites.google.com/site/scriptsexamples/learn-by-example/uiapp-examples-code-snippets/progress-indicators
var spinner = app.createImage('https://5079980847011989849-a-1802744773732722657'+
'-s-sites.googlegroups.com/site/scriptsexamples/ProgressSpinner.gif')
.setVisible(false)
.setId('spinner');
// Client handler for loadbtn will start spinner when button clicked
// Server handler will stop spinner when done loading pictures
var loadSpinner = app.createClientHandler()
.forTargets(spinner)
.setVisible(true);
loadbtn.addClickHandler(loadSpinner);
var loadhandler = app.createServerHandler('loadPics');
loadhandler.addCallbackElement(stackpanel);
loadbtn.addClickHandler(loadhandler);
grid
.setWidget(1, 0, insertlabel)
.setWidget(1, 1, inserttxtbox)
.setWidget(2, 0, daylabel)
.setWidget(2, 1, dayListBox)
.setWidget(3, 1, loadbtn)
.setWidget(3, 2, resetbtn)
.setWidget(4, 2, spinner);
for (var img = 0, row = 5; img < maxImgs; img++) {
var image = app.createImage().setPixelSize(250, 250).setId('image' + img).setVisible(false);
var imageName = app.createLabel().setId('name'+img).setVisible(false);
var imageAttr = app.createLabel().setId('attr'+img).setVisible(false);
var vertPan = app.createVerticalPanel().add(imageName).add(imageAttr).add(image);
grid.setWidget(row + Math.floor(img / 3), 1 + (img % 3), vertPan)
}
abspanel.add(titleLabel);
stackpanel.add(grid);
app.add(abspanel);
app.add(stackpanel);
return app;
}
function loadPics(e) {
e = {};
e.parameter = {};
e.parameter.ttbox = '0AmkSPNhhUowadFMxdDhpaXFlUFdMNkstaUZPdU5mR2c'
e.parameter.sday = 'P - Mon'
var app = UiApp.getActiveApplication();
var ss = SpreadsheetApp.openById(e.parameter.ttbox);
var list = ss.getSheetByName(e.parameter.sday);
var data = list.getDataRange().getValues().splice(1); // Get whole spreadsheet, without headers
for (var row = 0, img = 0; row < data.length && img < maxImgs; row++) {
var rowData = data[row];
if (rowData[0] != '') {
var image = app.getElementById('image' + img);
var imageName = app.getElementById('name'+img);
var imageAttr = app.getElementById('attr'+img);
image.setUrl(rowData[colUrl])
.setTitle(rowData[colName].toString() === '' ? 'image'+img : rowData[colName])
.setVisible(true);
imageName.setText(rowData[colName])
.setVisible(true);
imageAttr.setText(rowData[colAttr])
.setVisible(true);
img++;
}
}
// Done loading, hide spinner
app.getElementById('spinner').setVisible(false);
return app;
}

Related

How do I handle loops in my Google Sheets Script so that multiple (but not all) scripts run with one command?

My sheet is structured as follows:
1) A dropdown menu is triggered and opens when sheet is opened.
2) The dropdown menu has three options:
Search.
Run.
Upload.
SEARCH opens a dialogue box that asks for a name and case number which are in turn placed in designated cells in my Google Sheet.
RUN searches my Gmail, Google documents, and Google calendars for results that match the search criteria.
UPLOAD creates calendar entries based on the results from RUN.
My goal
I want to have those scripts associated with RUN also operate with SEARCH.
I want the script to automatically search my Gmail, documents, and calendars for results that match the search criteria when I click SEARCH and enter search terms in the dialogue boxes without then also having to click RUN from the dropdown menu.
I want showPrompt to also run saveEmails but NOT eventcreator1.
I then want to rename RUN to RE-RUN so that it still does what it does (runs saveEmails but NOT eventcreator1) without having to re-enter search terms unless I'm searching for a new case.
I have tried repeatedly to delete or reorder my loops to no avail. I just can't get it right.
This is current code:
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('WAYNE+')
.addItem('Search', 'showPrompt')
.addItem('RUN↓', 'saveEmails')
.addItem('Upload Time↑', 'eventcreator1')
.addSeparator()
.addToUi();
}
function showPrompt() {
var ui = SpreadsheetApp.getUi(); // Same variations.
var result = ui.prompt(
'Welcome',
'ENTER CASE#:',
ui.ButtonSet.OK_CANCEL);
var result1 = ui.prompt(
'Welcome',
'ENTER Client Name [First Last]:',
ui.ButtonSet.OK_CANCEL);
var button = result.getSelectedButton();
var button1 = result1.getSelectedButton();
var text = result.getResponseText();
var text1 = result1.getResponseText();
if (button == ui.Button.OK) {
// User clicked "OK".
var sheet1 = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = sheet1.getSheets()[0];
var sh1 = sheet1.getSheets()[1];
var datePlace = sh1.getRange("B3");
datePlace.setValue(text);
if (button1 == ui.Button.OK) {
// User clicked "OK".
var sheet1 = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = sheet1.getSheets()[0];
var sh1 = sheet1.getSheets()[1];
var searchCriteria = sh1.getRange("B2");
searchCriteria.setValue(text1);
}}}
var sheet1 = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = sheet1.getSheets()[0];
var sh1 = sheet1.getSheets()[1];
var sh2 = sheet1.getSheets()[2];
var sh3 = sheet1.getSheets()[3];
var sh4 = sheet1.getSheets()[4];
var sh5 = sheet1.getSheets()[5];
var sh6 = sheet1.getSheets()[6];
var sh7 = sheet1.getSheets()[7];
var sh8 = sheet1.getSheets()[8];
var sh9 = sheet1.getSheets()[9];
var sh10 = sheet1.getSheets()[10];
var range = sh3.getRange("C2:C1000");
var arrowRange = sh1.getRange("B14");
var editClearRange = sh3.getRange("E2:E");
var search1 = sh1.getRange("F8").getValue();
var searchBB = sh1.getRange("F5").getValue();
var SEARCH_QUERY = search1;
// Credit: https://gist.github.com/oshliaer/70e04a67f1f5fd96a708
function getEmails_(q) {
var arrowRange=sh1.getRange("B14");
var dupePreventRange = sh1.getRange("F14");
sh0.clear();
sh7.clear();
editClearRange.clear();
dupePreventRange.clear();
sh9.getRange("A1").clear;
arrowRange.setValue("↓");
var emails = [];
var threads = GmailApp.search(q);
for (var i in threads) {
var msgs = threads[i].getMessages();
for (var j in msgs) {
emails.push([msgs[j].getDate(), msgs[j].getPlainBody().substring(0, 49000), msgs[j].getSubject(), msgs[j].getFrom(), msgs[j].getTo()]);
}
}
return emails;
}
function appendData_(sh0, array2d) {
sh0.getRange(sh0.getLastRow() + 1, 1, array2d.length, array2d[0].length).setValues(array2d);
}
function saveEmails() {
var array2d = getEmails_(SEARCH_QUERY);
if (array2d) {
appendData_(sh0, array2d);
}
var mycal20 = "loremipsum.com_5555554373830392d363336#resource.calendar.google.com"; // MASTER
var cal20 = CalendarApp.getCalendarById(mycal20);
var events20 = cal20.getEvents(new Date("January 12, 1990 00:00:00 EST"), new Date("May 18, 2050 23:59:59 EST"), {search:(searchBB)});
var row20=sh0.getLastRow()+1;
var range20 = sh0.getRange(row20,1,1,14);
for (var k=0;k<events20.length;k++) {
var row20=sh0.getLastRow()+1;
var details20=[[events20[k].getStartTime(), events20[k].getDescription(), events20[k].getTitle(),mycal20]];
var range20=sh0.getRange(row20,1,1,4);
range20.setValues(details20);
Utilities.sleep(10000);
var r1 = sh3.getRange("C2:C1000").getValues();
var cell = sh3.getRange("D2:D1000");
cell.setNotes(r1);
}
var mycalSTAFF = "loremipsum.com_55555kr58832tjiach0psil3ss#group.calendar.google.com";
var STAFFcal = CalendarApp.getCalendarById(mycalSTAFF);
var eventsSTAFF = STAFFcal.getEvents(new Date("January 12, 1990 00:00:00 EST"), new Date("May 18, 2050 23:59:59 EST"), {search:(searchBB)});
var STAFFrange = sh7.getRange(1,1,1,14);
for (var j=0;j<eventsSTAFF.length;j++) {
var rowSTAFF=j+1;
var detailsSTAFF=[[mycalSTAFF,eventsSTAFF[j].getStartTime()]];
var STAFFrange=sh7.getRange(rowSTAFF,1,1,2);
STAFFrange.setValues(detailsSTAFF);
}
var mycalAA = "loremipsum.com_cq6ugmln55555cnlokhkl5555#group.calendar.google.com";
var AAcal = CalendarApp.getCalendarById(mycalAA);
var eventsAA = AAcal.getEvents(new Date("January 12, 1990 00:00:00 EST"), new Date("May 18, 2050 23:59:59 EST"), {search:(searchBB)});
var AArange = sh7.getRange(1,1,1,14);
for (var k=0;k<eventsAA.length;k++) {
var rowAA=sh7.getLastRow()+1;
var detailsAA=[[mycalAA,eventsAA[k].getStartTime()]];
var AArange=sh7.getRange(rowAA,1,1,2);
AArange.setValues(detailsAA);
}
var mycalCC = "loremipsum.com_pf50prnil2u55555vjo555555#group.calendar.google.com";
var CCcal = CalendarApp.getCalendarById(mycalCC);
var eventsCC = CCcal.getEvents(new Date("January 12, 1990 00:00:00 EST"), new Date("May 18, 2050 23:59:59 EST"), {search:(searchBB)});
var CCrange = sh7.getRange(1,1,1,14);
for (var l=0;l<eventsCC.length;l++) {
var rowCC=sh7.getLastRow()+1;
var detailsCC=[[mycalCC, eventsCC[l].getStartTime()]];
var CCrange=sh7.getRange(rowCC,1,1,2);
CCrange.setValues(detailsCC);
}
var mycalDD = "loremipsum.com_aer92sd55555ncf7v6i8lpt6i6j555c#group.calendar.google.com";
var DDcal = CalendarApp.getCalendarById(mycalDD);
var eventsDD = DDcal.getEvents(new Date("January 12, 1990 00:00:00 EST"), new Date("May 18, 2050 23:59:59 EST"), {search:(searchBB)});
var DDrange = sh7.getRange(1,1,1,14);
for (var x=0;x<eventsDD.length;x++) {
var rowDD=sh7.getLastRow()+1;
var detailsDD=[[mycalDD,eventsDD[x].getStartTime()]];
var DDrange=sh7.getRange(rowDD,1,1,2);
DDrange.setValues(detailsDD);
}
var mycalBB = "loremipsum.com_53naqi1i92h5555qor96ll555a1g#group.calendar.google.com";
var BBcal = CalendarApp.getCalendarById(mycalBB);
var eventsBB = BBcal.getEvents(new Date("January 12, 1990 00:00:00 EST"), new Date("May 18, 2050 23:59:59 EST"), {search:(searchBB)});
var BBrange = sh7.getRange(1,1,1,14);
for (var r=0;r<eventsBB.length;r++) {
var rowBB=sh7.getLastRow()+1;
var detailsBB=[[mycalBB, eventsBB[r].getStartTime(),eventsBB[r].getDescription()]];
var BBrange=sh7.getRange(rowBB,1,1,3);
BBrange.setValues(detailsBB);
}}
var timeStampRange = sh1.getRange("A14");
var timeStamp = new Date();
timeStampRange.setValue(timeStamp);
function search_files() {
}
var sheet1 = SpreadsheetApp.getActiveSpreadsheet();
var sh1 = sheet1.getSheets()[1];
var search0 = sh1.getRange("C7").getValue();
var search5 = sh1.getRange("B3").getValue();
var searchFor = 'title contains "BB R&E"' + 'and fullText contains "' + search5 + '"';
var files = DriveApp.searchFiles(searchFor);
while (files.hasNext()) {
var file = files.next();
Logger.log (searchFor);
Logger.log(file.getName());
}
var sheet1 = SpreadsheetApp.getActiveSpreadsheet();
var sh1 = sheet1.getSheets()[1];
var search0 = sh1.getRange("C7").getValue();
var search5 = sh1.getRange("B3").getValue();
var searchFor1 = 'title contains "BB R&E"' + 'and fullText contains "' + search0 + '"';
var files1 = DriveApp.searchFiles(searchFor1);
while (files1.hasNext()) {
var file1 = files1.next();
Logger.log (searchFor1);
Logger.log(file1.getName());
}
var body = Logger.getLog().substring(0, 49000);
var rangeTHOMAS=sh9.getRange("A1");
rangeTHOMAS.setValue(body);
function eventcreator1() {
var arrowRange=sh1.getRange("B14");
var dupePreventRange = sh1.getRange("F14");
if (dupePreventRange.isBlank()){
var dupePreventRange = sh1.getRange("F14");
dupePreventRange.setValue("HELLO");
var arrowRange=sh1.getRange("B14");
var startRow = 2; // First row of data to process
var numRows = 100; // Number of rows to process
var dataRange = sh5.getRange(startRow, 1, numRows, 5);
var data = dataRange.getValues();
var mycal = "loremipsum.com_55555ugmlnoaqfacn5555lokhkl55554#group.calendar.google.com";
var cal = CalendarApp.getCalendarById(mycal);
for (i in data) {
var row = data[i];
var title = row[0]; // First column
var date1 = row[1]; // Second column
var desc = row[2];
arrowRange.setValue("↑");
cal.createAllDayEvent(title,
new Date(date1),
{description: desc});
Utilities.sleep(250);
}
var startRow1 = 2; // First row of data to process
var numRows1 = 100; // Number of rows to process
var dataRange1 = sh6.getRange(startRow1, 1, numRows1, 5);
var data1 = dataRange1.getValues();
var mycal1 = "loremipsum.com_555557kri8832tjiach0p5555sil3ss#group.calendar.google.com";
var cal1 = CalendarApp.getCalendarById(mycal1);
for (i in data1) {
var row1 = data1[i];
var title1 = row1[0]; // First column
var date2 = row1[1]; // Second column
var desc1 = row1[2];
cal1.createAllDayEvent(title1,
new Date(date2),
{description: desc1});
Utilities.sleep(250);
}
var startRow2 = 2; // First row of data to process
var numRows2 = 450; // Number of rows to process
var dataRange2 = sh8.getRange(startRow1, 1, numRows1, 5);
var data2 = dataRange2.getValues();
var mycal2 = "loremipsum.com_5355555aqi1i92hl3nmqo55555lea1g#group.calendar.google.com";
var cal2 = CalendarApp.getCalendarById(mycal2);
for (i in data2) {
var row2 = data2[i];
var title2 = row2[0]; // First column
var date3 = row2[1]; // Second column
var desc2 = row2[2];
cal2.createAllDayEvent(title2,
new Date(date3),
{description: desc2});
Utilities.sleep(250);
}
var startRow3 = 2; // First row of data to process
var numRows3 = 100; // Number of rows to process
var dataRange3 = sh10.getRange(startRow1, 1, numRows1, 5);
var data3 = dataRange3.getValues();
var mycal3 = "loremipsum.com_55555aqi1i92hl3nmqo55555lea1g#group.calendar.google.com";
var cal3 = CalendarApp.getCalendarById(mycal3);
for (i in data2) {
var row3 = data3[i];
var title3 = row3[0]; // First column
var date4 = row3[1]; // Second column
var desc3 = row3[2];
cal3.createAllDayEvent(title3,
new Date(date4),
{description: desc3});
Utilities.sleep(250);
var timeStampRange = sh1.getRange("A14");
var timeStamp = new Date();
timeStampRange.setValue(timeStamp);
}}}
I haven't gone through your code thoroughly for obvious reasons, but adding saveEmails() at the beginning of the showPrompt function wouldn't solve the issue?
This way every time Search is selected, it would be as if RUN was clicked too, wouldn't it?

How to create a new document from a template with placeholders

I'm trying to create a script that will create new documents from a template-document. Replace placeholders in the documents with data from the sheet based on a keyword search in a specific column. And then change the row's value in the specific column so that the row will not process when the script runs again.
I think I've got it right with the first keyword search, and the loop through the rows. But the last part to get the data to 'merge' to the placeholders I can't figure out how to. I just get the value "object Object" and other values in the document.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var lastColumn = s.getLastColumn();
function createDocFromSheet() {
var headers = getUpsertHeaders(s);//function is defined outside of this function
var statusColNum = headers.indexOf('Status')+1;
var row = getRowsData(s); //The function is defined outside this function.
for (var i=0; i<row.length; i++) {
var jobStatus = '';
if (row[i]['Status'] === '') {
//New: write the status to the correct row and column - this will be moved to the end when I get the rest right
var jobStatus = "Created";
s.getRange(i+2, statusColNum).setValue(jobStatus);
//Find the template and make a copy. Activate the body of the new file.
var templateFile = DriveApp.getFileById('1lkfmqsJMjjPujHqDqKtcDmL-5GMIxpOWTyCOaK29d2A');
var copyFile = templateFile.makeCopy()
var copyId = copyFile.getId()
var copyDoc = DocumentApp.openById(copyId)
var copyBody = copyDoc.getActiveSection()
//Find the rows Values as an object.
var rows = s.getRange(i+2,1,1,lastColumn)
var rowsValues = rows.getValues();
Logger.log(rowsValues)
//Until here I think it's okay but the last part?
//HOW TO replace the text???
for (var columnIndex = 0; columnIndex < lastColumn; columnIndex++) {
var headerValue = headerRow[columnIndex]
var rowValues = s.getActiveRange(i,columnIndex).getValues()
var activeCell = rowsValues[columnIndex]
//var activeCell = formatCell(activeCell);
Logger.log(columnIndex);
copyBody.replaceText('<<' + headerValue + '>>', activeCell)
}
Template doc : Link
Template sheet: Link
You can use the following GAS code to accomplish your goals:
var DESTINATION_FOLDER_ID = 'YOUR_DESTINATION_FOLDER_ID';
var TEMPLATE_FILE_ID = 'YOUR_TEMPLATE_FILE_ID';
function fillTemplates() {
var sheet = SpreadsheetApp.getActiveSheet();
var templateFile = DriveApp.getFileById(TEMPLATE_FILE_ID);
var values = sheet.getDataRange().getDisplayValues();
var destinationFolder = DriveApp.getFolderById(DESTINATION_FOLDER_ID);
for (var i=1; i<values.length; i++) {
var rowElements = values[i].length;
var fileStatus = values[i][rowElements-1];
if (fileStatus == 'Created') continue;
var fileName = values[i][0];
var newFile = templateFile.makeCopy(fileName, destinationFolder);
var fileToEdit = DocumentApp.openById(newFile.getId());
for (var j=1; j<rowElements-1; j++) {
var header = values[0][j];
var docBody = fileToEdit.getBody();
var patternToFind = Utilities.formatString('<<%s>>', header);
docBody.replaceText(patternToFind, values[i][j]);
}
sheet.getRange(i+1, rowElements).setValue('Created');
}
}
You only have to replace the 1st and 2nd lines as appropriate. Please do consider as well that the code will assume that the first column is the file name, and the last one the status. You can insert as many columns as you wish in between.
After some coding I ended up with this code to process everything automatic.
Again thanks to #carlesgg97.
The only thing I simply can't figure out now is how to generate the emailbody from the template with dynamic placeholders like in the document. How to generate the var patternToFind - but for the emailbody?
I've tried a for(var.... like in the document but the output doesn't replace the placeholders.
var DESTINATION_FOLDER_ID = '1inwFQPmUu1ekGGSB5OnWLc_8Ac80igK0';
var TEMPLATE_FILE_ID = '1lkfmqsJMjjPujHqDqKtcDmL-5GMIxpOWTyCOaK29d2A';
function fillTemplates() {
//Sheet variables
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');
var values = sheet.getDataRange().getDisplayValues();
//Header variables
var headers = sheet.getDataRange().getValues().shift();
var idIndex = headers.indexOf('ID');
var nameIndex = headers.indexOf('Name');
var emailIndex = headers.indexOf('Email');
var subjectIndex = headers.indexOf('Subject');
var statusIndex = headers.indexOf('Status');
var fileNameIndex = headers.indexOf('File Name');
var filerIndex = headers.indexOf('Filer');
var birthIndex = headers.indexOf('Date of birth');
//Logger.log(statusIndex)
//Document Templates ID
var templateFile = DriveApp.getFileById(TEMPLATE_FILE_ID);
//Destination
var destinationFolder = DriveApp.getFolderById(DESTINATION_FOLDER_ID);
var templateTextHtml = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Email').getRange('D11').getValue();
//Run through the variables
for (var i=1; i<values.length; i++) {
//If first column is empty then stop
var index0 = values[i][0];
if(index0 == "") continue;
var rowElements = values[i].length;
var fileStatus = values[i][statusIndex];
//If the row already processed then stop
if (fileStatus == "Created") continue;
//If the row is not processed continue
//Define the new filename by the relevant Column
var fileName = values[i][fileNameIndex];
var newFile = templateFile.makeCopy(fileName, destinationFolder);
var fileToEdit = DocumentApp.openById(newFile.getId());
//Replace placeholders in the new document
for (var j=1; j<rowElements-1; j++) {
var header = values[0][j];
var docBody = fileToEdit.getBody();
var patternToFind = Utilities.formatString('{{%s}}', header);
docBody.replaceText(patternToFind, values[i][j]);
}
//Create the PDF file
fileToEdit.saveAndClose();
var newPdf = DriveApp.createFile(fileToEdit.getAs('application/pdf'));
DriveApp.getFolderById(DESTINATION_FOLDER_ID).addFile(newPdf);
DriveApp.getRootFolder().removeFile(newPdf);
newFile.setTrashed(true);
var newPdfUrl = newPdf.getUrl();
//Create the emailbody
var textBodyHtml = templateTextHtml.replace("{{Name}}",values[i][nameIndex]).replace("{{Date of birth}}",values[i][birthIndex]);
var textBodyPlain = textBodyHtml.replace(/\<br>/mg,"");
//Will send email to email Column
var email = values[i][emailIndex];
var emailSubject = values[i][idIndex]+" - "+values[i][fileNameIndex]+" - "+values[i][nameIndex];
MailApp.sendEmail(email,emailSubject,textBodyPlain,
{
htmlBody: textBodyHtml+
"<p>Automatic generated email</p>",
attachments: [newPdf],
});
sheet.getRange(i+1, filerIndex+1).setValue(newPdfUrl);
sheet.getRange(i+1, statusIndex+1).setValue('Created');
}//Close for (var i=1...
}

Google Docs Script: appendText/insertText Formatting

How do I use appendText() or insertText() for a Google Doc script and maintain formatting?
I want to format the middle portion (group2) of appended strings with italics, while leaving the other parts (group1, group3) as normal text. For example: Hi my name is Nate.
I can bring in "Hi" and append "my name is" and it formats correctly. When I try to append (or insert) "Nate," "Nate" is italicized as well.Between operators +, appendText(), and insertText(), I'm not having much luck.
Below is the relevant portion of the script. Below that, is the entire thing.
How can I append 3 strings together, and only format the middle portion?
NOTE: I commented-out the things I tried (trial1, trial2, etc.). I also started HERE and used it as a guide.
Thanks for any help you can offer!
RELEVANT PART:
if (author1 != "") {
var group1 = author1+author2+author3;
var group2 = title2Italics+containerItalics;
var group3 = contribution1+contribution2+contribution3+version+number+publisher+pubDate+location;
//Only using the calculations below to determine the offset for insertText
var group1Length = group1.length;
var group2Length = group2.length;
var offset = group1Length+group2Length
Logger.log(group1Length);
Logger.log(group2Length);
Logger.log(offset);
//Determines if italicizing is necessary
if (group2.length > 0) {
var addG1 = body.insertParagraph(0,group1)
var addG2 = addG1.appendText(group2);
var formatItalics = addG2.editAsText().setItalic(true);
//var trial1 = addG2.editAsText().setItalic(true) + group3; //does not return the contents of "group3"
//var trial2 = formatItalics + group3; //does not return the contents of "group3"
//var trial3 = formatItalics.insertText(offset,group3); //Error: "Index (18) must be less than or equal to the content length (6)."
//var trial4 = formatItalics.insertText(group2Length, group3); //formats "group3" as well
//var trial5 = formatItalics.appendText(group3); //formats "group3" as well
}
//If italicizing is NOT necessary
else {
var cite = body.insertParagraph(0,group1 + group3);
} //ELSE STATEMENT ENDS HERE
} //FIRST IF STATEMENT ENDS HERE
ENTIRE SCRIPT:
function mlaBibTest() {
// Sheet Information
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('test'));
var startRow = 3;
var startCol = 21;
var numRows = sheet.getLastRow()-1;
var numCols = 14;
var dataRange = sheet.getRange(startRow, startCol, numRows, numCols);
// Document information
var doc = DocumentApp.openById('13MlHq_uoO1rUF0RfdF_kBlLJjbGt4aDoOcSWef0V4zM');
var body = doc.getBody();
// Fetch values for each row in the SS Range.
var cells = dataRange.getValues();
for (var i = 0; i < cells.length; ++i) {
var column = cells[i];
var colU = column[0];
var colV = column[1];
var colW = column[2];
var colX = column[3];
var colY = column[4];
var colZ = column[5];
var colAA = column[6];
var colAB = column[7];
var colAC = column[8];
var colAD = column[9];
var colAE = column[10];
var colAF = column[11];
var colAG = column[12];
var colAH = column[13];
var author1 = colU;
var author2 = colV;
var author3 = colW;
var title1Quotes = colX;
var title2Italics = colY;
var containerItalics = colZ;
var contribution1 = colAA;
var contribution2 = colAB;
var contribution3 = colAC;
var version = colAD;
var number = colAE;
var publisher = colAF;
var pubDate = colAG;
var location = colAH;
if (author1 != "") {
var group1 = author1+author2+author3;
var group2 = title2Italics+containerItalics;
var group3 = contribution1+contribution2+contribution3+version+number+publisher+pubDate+location;
//Only using the calculations below to determine the offset for insertText
var group1Length = group1.length;
var group2Length = group2.length;
var offset = group1Length+group2Length
Logger.log(group1Length);
Logger.log(group2Length);
Logger.log(offset);
//Determines if italicizing is necessary
if (group2.length > 0) {
var addG1 = body.insertParagraph(0,group1)
var addG2 = addG1.appendText(group2);
var formatItalics = addG2.editAsText().setItalic(true);
//var trial1 = addG2.editAsText().setItalic(true) + group3; //does not return the contents of "group3"
//var trial2 = formatItalics + group3; //does not return the contents of "group3"
//var trial3 = formatItalics.insertText(offset,group3); //Error: "Index (18) must be less than or equal to the content length (6)."
//var trial4 = formatItalics.insertText(group2Length, group3); //formats "group3" as well
//var trial5 = formatItalics.appendText(group3); //formats "group3" as well
}
//If italicizing is NOT necessary
else {
var cite = body.insertParagraph(0,group1 + group3);
} //ELSE STATEMENT ENDS HERE
} //FIRST IF STATEMENT ENDS HERE
} //FOR LOOP ENDS HERE
SpreadsheetApp.flush();
} // FUNCTION ENDS HERE
This is a simple example of doing what you asked. It's important to remember that setItalics(true) sets a persistent setting for all new text to be italic, so we have to set it back to false after.
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var paragraph = body.insertParagraph(0, ""); //add paragparh at top of body.
var text1 = paragraph.appendText("Not Italics ");
var text2 = paragraph.appendText("Italics ");
text2.setItalic(true); //Everything after and including this will be italics
var text3 = paragraph.appendText("Not Italics");
text3.setItalic(false); //Everything after and including this will not be italics
>Not Italics Italics Not Italics
So it's easier if you set italics as you build the paragraph.

Refresh Array of Images- Google Script

I want to be able to clear the whole array of images with the click of a button and reload the array with updated values. I cannot get this to work by clearing the vertPanel. Can this be done by somehow resetting all the data? Any help would be appreciated.
var maxImgs = 6; // Number of images in grid
var colUrl = 0; // Column containing URL
var colName = 2; // Column containing Name
var colAttr = 1; // Column containing Attributes
function doGet(e) {
var app = UiApp.createApplication().setTitle('Not Here');
var abspanel = app.createAbsolutePanel().setStyleAttribute('padding','25px');
var grid = app.createGrid(8, 8);
var titleLabel = app.createLabel('Not Here');
titleLabel.setStyleAttribute('margin-left','85px');
titleLabel.setStyleAttribute("font-size", "135%");
titleLabel.setStyleAttribute("font-weight", "bold");
var insertlabel = app.createLabel('Which Schedule? (Insert Document Key)');
var inserttxtbox = app.createTextBox().setId('txtbox').setName('ttbox').setMaxLength(44);
var loadbtn = app.createButton('Load Pictures').setId('loadbtn');
var resetbtn = app.createButton('Refresh').setId('rbtn').setVisible(false);
var daylabel = app.createLabel('Select Day');
var mon = "P - Mon"
var tues = "P - Tues"
var wed = "P - Wed"
var thurs = "P - Thurs"
var fri = "P - Fri"
var dayListBox = app.createListBox().setWidth('140px').setId('day').setName('sday')
dayListBox.addItem(mon);
dayListBox.addItem(tues);
dayListBox.addItem(wed);
dayListBox.addItem(thurs);
dayListBox.addItem(fri);
// Borrowed from https://sites.google.com/site/scriptsexamples/learn-by-example/uiapp-examples- code-snippets/progress-indicators
var spinner = app.createImage('https://dl.dropboxusercontent.com/u/211279/loading3T.gif')
.setVisible(false)
.setId('spinner');
// Client handler for loadbtn will start spinner when button clicked
// Server handler will stop spinner when done loading pictures
var loadSpinner = app.createClientHandler()
.forTargets(spinner)
.setVisible(true);
loadbtn.addClickHandler(loadSpinner);
var loadhandler = app.createServerHandler('loadPics');
loadhandler.addCallbackElement(abspanel);
loadbtn.addClickHandler(loadhandler);
grid
.setWidget(1, 0, insertlabel)
.setWidget(1, 1, inserttxtbox)
.setWidget(2, 0, daylabel)
.setWidget(2, 1, dayListBox)
.setWidget(3, 1, loadbtn)
.setWidget(3, 2, resetbtn)
.setWidget(2, 2, spinner)
.setCellSpacing(5);
for (var img = 0, row = 5; img < maxImgs; img++) {
var image = app.createImage().setPixelSize(350, 350).setId('image' + img);
var imageName = app.createLabel('name').setId('name'+img);
var imageAttr = app.createLabel('attr').setId('attr'+img);
var vertPan = app.createVerticalPanel().add(imageName).add(imageAttr).add(image).setStyleAttributes({'padding':'15px','borderStyle':'solid','border-radius':'15px','background':'silver'}).setVisible(false).setId('vertPanel'+img);
grid.setWidget(row + Math.floor(img / 4), 1 + (img % 4), vertPan)
}
abspanel.add(titleLabel);
abspanel.add(grid);
app.add(abspanel);
return app;
}
function loadPics(e) {
var app = UiApp.getActiveApplication();
var ss = SpreadsheetApp.openById(e.parameter.ttbox);
var list = ss.getSheetByName(e.parameter.sday);
var data = list.getRange("A121:C230").getValues().splice(1); // Get whole spreadsheet, without headers
for (var row = 0, img = 0; row < data.length && img < maxImgs; row++) {
var rowData = data[row];
if (rowData[0] != '') {
var image = app.getElementById('image' + img);
var imageName = app.getElementById('name'+img);
var imageAttr = app.getElementById('attr'+img);
var vertPan = app.getElementById('vertPanel'+img).setVisible(true);
image.setUrl(rowData[colUrl])
.setTitle(rowData[colName].toString() === '' ? 'image'+img : rowData[colName]);
imageName.setText(rowData[colName]).setStyleAttribute("font-size", "150%");
imageAttr.setText(rowData[colAttr]);
img++;
}
}
// Done loading, hide spinner
app.getElementById('spinner').setVisible(false);
return app;
}
Better define another grid and add it to abspanel, In the handler function, call the image grid by ID and then use method clear(); to clear the grid. And then reconstruct it for new images.
I hope you get it what I am trying to say.
in doGet() function use
var imgGrid = app.createGrid(1,1).setId('imgGrid');
abspanel.add(imgGrid);
in your handler function use
var imgGrid = app.getElementById('imgGrid').clear();
imgGrid.resize(row, column);
//Now manipulate this grid to show new images

Class Error Vertical Panel--Google Apps

I am getting a class error when I add a vertical panel to my widget and cannot seem to find why. Can you even add a vertical panel to a widget? Or is there maybe another way I can add to the Name and Attribute Labels outside of a Vertical Panel?
maxImgs = 6; // Number of images in grid
colUrl = 45; // Column containing URL
colName = 48; // Column containing Name
colAttr = 46; // Column containing Attributes
function doGet(e) {
var app= UiApp.createApplication().setTitle('Not Here')
var abspanel= app.createAbsolutePanel();//.setHeight('100%').setWidth('100%');
var stackpanel=app.createStackPanel();
var grid = app.createGrid(8,8);
var titleLabel= app.createLabel('Not Here');
titleLabel.setStyleAttribute("text-align", "center");
titleLabel.setStyleAttribute("font-size", "135%");
titleLabel.setStyleAttribute("font-weight", "bold");
var insertlabel= app.createLabel('Which Schedule? (Insert Document Key)');
var inserttxtbox=app.createTextBox().setId('txtbox').setName('ttbox').setMaxLength(44);
var loadbtn= app.createButton('Load Pictures').setId('loadbtn');
var resetbtn= app.createButton('Refresh').setId('rbtn').setVisible(false);
var daylabel= app.createLabel('Select Day');
var mon= "P - Mon"
var tues= "P - Tues"
var wed= "P - Wed"
var thurs= "P - Thurs"
var fri= "P - Fri"
var dayListBox= app.createListBox().setWidth('140px').setId('day').setName ('sday')
dayListBox.addItem(mon);
dayListBox.addItem(tues);
dayListBox.addItem(wed);
dayListBox.addItem(thurs);
dayListBox.addItem(fri);
var spinner= app.createImage('http://www.zho.ae/_layouts/ZHO/AR/Images/loader_spinner.gif').setVisible(false).setId('spinner');
var loadSpinner = app.createClientHandler()
.forTargets(spinner)
.setVisible(true);
loadbtn.addClickHandler(loadSpinner);
var loadhandler=app.createServerHandler('loadPics');
loadhandler.addCallbackElement(stackpanel);
loadbtn.addClickHandler(loadhandler);
grid
.setWidget(1,0,insertlabel)
.setWidget(1,1,inserttxtbox)
.setWidget(2,0, daylabel)
.setWidget(2,1, dayListBox)
.setWidget(3,1, loadbtn)
.setWidget(3,2,resetbtn)
.setWidget(4,2,spinner)
var image = [];
for (var img = 0, row = 5; img < maxImgs; img++) {
image[img] = app.createImage().setPixelSize(250, 250).setId('image' + img).setVisible(false);
var imageName = app.createLabel().setId('name'+img).setVisible(false);
var imageAttr = app.createLabel().setId('attr'+img).setVisible(false);
var vertPan = app.createVerticalPanel().add(imageName).add(imageAttr).add(image);
grid.setWidget(row + Math.floor(img / 3), 1 + (img % 3), vertPan);
}
abspanel.add(titleLabel);
stackpanel.add(grid);
app.add(abspanel);
app.add(stackpanel);
return app;
}
function loadPics(e){
var app= UiApp.getActiveApplication();
var ss= SpreadsheetApp.openById(e.parameter.ttbox);
var list=ss.getSheetByName(e.parameter.sday);
var data = list.getDataRange().getValues().splice(1); // Get whole spreadsheet, without headers
// In this example, URLs are in A, Name in B, Attributes in C
for (var row = 0, img = 0; row < data.length && img < maxImgs; row++) {
var rowData = data[row];
if (rowData[colUrl] != '') {
var image = app.getElementById('image' + img);
var imageName = app.getElementById('name'+img);
var imageAttr = app.getElementById('attr'+img);
image.setUrl(rowData[colUrl])
.setTitle(rowData[colName].toString() === '' ? 'image'+img : rowData[colName])
.setVisible(true);
imageName.setText(rowData[colName])
.setVisible(true);
imageAttr.setText(rowData[colAttr])
.setVisible(true);
img++;
}
}
app.getElementById('spinner').setVisible(false);
return app;
}
The error doesn't come from the vertical panel... You're adding image which is an array of widgets, not a UiApp widget.
Try to add array elements in a for loop instead, something like
var vertPan = app.createVerticalPanel().add(imageName).add(imageAttr);
for(var n in image){vertPan.add(image[n])};
EDIT : I re-read Mogsdad's answer on your other post and his code was different... you won't get that nice grid result with this version of the code ... I 'm not sure I understand why you created that array ???
EDIT2 : just for testing I tried Mogsdad's code with this slight modification to see how it shows up ...
for (var img = 0, row = 5; img < maxImgs; img++) {
var image = app.createImage().setPixelSize(250, 250).setId('image' + img).setVisible(true);
var imageName = app.createLabel('name').setId('name'+img).setVisible(true);
var imageAttr = app.createLabel('attr').setId('attr'+img).setVisible(true);
var vertPan = app.createVerticalPanel().add(imageName).add(imageAttr).add(image);
grid.setWidget(row + Math.floor(img / 3), 1 + (img % 3), vertPan)
}
and I get this :
EDIT 3 : here is a modified verion of Mogsdad's code that should allow you to see more easily what is going on and is in a 2x2 matrix with visible (and colored) panels...
maxImgs = 4; // Number of images in grid
colUrl = 3; // Column containing URL
colName = 0; // Column containing Name
colAttr = 1; // Column containing Attributes
function doGet(e) {
var app = UiApp.createApplication().setTitle('Not Here');
var abspanel = app.createAbsolutePanel().setStyleAttribute('padding','25px');
var grid = app.createGrid(8, 8);
var titleLabel = app.createLabel('Not Here');
titleLabel.setStyleAttribute('margin-left','85px');
titleLabel.setStyleAttribute("font-size", "135%");
titleLabel.setStyleAttribute("font-weight", "bold");
var insertlabel = app.createLabel('Which Schedule? (Insert Document Key)');
var inserttxtbox = app.createTextBox().setId('txtbox').setName('ttbox').setMaxLength(44);
var loadbtn = app.createButton('Load Pictures').setId('loadbtn');
var resetbtn = app.createButton('Refresh').setId('rbtn').setVisible(false);
var daylabel = app.createLabel('Select Day');
var mon = "P - Mon"
var tues = "P - Tues"
var wed = "P - Wed"
var thurs = "P - Thurs"
var fri = "P - Fri"
var dayListBox = app.createListBox().setWidth('140px').setId('day').setName('sday')
dayListBox.addItem(mon);
dayListBox.addItem(tues);
dayListBox.addItem(wed);
dayListBox.addItem(thurs);
dayListBox.addItem(fri);
// Borrowed from https://sites.google.com/site/scriptsexamples/learn-by-example/uiapp-examples-code-snippets/progress-indicators
var spinner = app.createImage('https://dl.dropboxusercontent.com/u/211279/loading3T.gif')
.setVisible(false)
.setId('spinner');
// Client handler for loadbtn will start spinner when button clicked
// Server handler will stop spinner when done loading pictures
var loadSpinner = app.createClientHandler()
.forTargets(spinner)
.setVisible(true);
loadbtn.addClickHandler(loadSpinner);
var loadhandler = app.createServerHandler('loadPics');
loadhandler.addCallbackElement(abspanel);
loadbtn.addClickHandler(loadhandler);
grid
.setWidget(1, 0, insertlabel)
.setWidget(1, 1, inserttxtbox)
.setWidget(2, 0, daylabel)
.setWidget(2, 1, dayListBox)
.setWidget(3, 1, loadbtn)
.setWidget(3, 2, resetbtn)
.setWidget(2, 2, spinner)
.setCellSpacing(5);
for (var img = 0, row = 5; img < maxImgs; img++) {
var image = app.createImage().setPixelSize(250, 250).setId('image' + img);
var imageName = app.createLabel('name').setId('name'+img);
var imageAttr = app.createLabel('attr').setId('attr'+img);
var vertPan = app.createVerticalPanel().add(imageName).add(imageAttr).add(image).setStyleAttributes({'padding':'15px','borderStyle':'solid','border-radius':'15px','background':'silver'}).setVisible(false).setId('vertPanel'+img);
grid.setWidget(row + Math.floor(img / 2), 1 + (img % 2), vertPan)
}
abspanel.add(titleLabel);
abspanel.add(grid);
app.add(abspanel);
return app;
}
function loadPics(e) {
e = {};
e.parameter = {};
e.parameter.ttbox = '0AnqSFd3iikE3dGFsUWNpb08zVWx5YjFRckloZ0NFZGc'
e.parameter.sday = 'Sheet1'
var app = UiApp.getActiveApplication();
var ss = SpreadsheetApp.openById(e.parameter.ttbox);
var list = ss.getSheetByName(e.parameter.sday);
var data = list.getDataRange().getValues().splice(1); // Get whole spreadsheet, without headers
for (var row = 0, img = 0; row < data.length && img < maxImgs; row++) {
var rowData = data[row];
if (rowData[0] != '') {
var image = app.getElementById('image' + img);
var imageName = app.getElementById('name'+img);
var imageAttr = app.getElementById('attr'+img);
var vertPan = app.getElementById('vertPanel'+img).setVisible(true);
image.setUrl(rowData[colUrl])
.setTitle(rowData[colName].toString() === '' ? 'image'+img : rowData[colName]);
imageName.setText(rowData[colName]);
imageAttr.setText(rowData[colAttr]);
img++;
}
}
// Done loading, hide spinner
app.getElementById('spinner').setVisible(false);
return app;
}
SS viewable here
demo app available here
You can see that labels correspond to images (only 4 first links are used)