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
Related
Looking to loop through the following script to set values in my target sheet for all entries below cell a21 in the 'order entry template' i've created in the 'PO Template' sheet.
function submit() {
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getSheetByName("POTemplate");
var PONo = activeSheet.getRange("N3").getValue();
var PODate = activeSheet.getRange("N4").getValue();
var SKU = activeSheet.getRange("a22").getValue();
var SKUDesc = activeSheet.getRange("d22").getValue();
var SKUQty = activeSheet.getRange("k22").getValue();
var UtCost = activeSheet.getRange("m22").getValue();
var ExtCost = activeSheet.getRange("p22").getValue();
var target = "POHistory";
var targetSheet = app.getActiveSpreadsheet().getSheetByName(target);
targetSheet.getRange(2, 1).setValue(PONo);
targetSheet.getRange(2, 2).setValue(PODate);
targetSheet.getRange(2, 3).setValue(SKU);
targetSheet.getRange(2, 4).setValue(SKUDesc);
targetSheet.getRange(2, 5).setValue(SKUQty)
targetSheet.getRange(2, 6).setValue(UtCost);
targetSheet.getRange(2, 7).setValue(ExtCost);
}
Here you are! Need to run now, I'll add comments later:
function submit() {
var app = SpreadsheetApp;
var tplSheet = app.getActiveSpreadsheet().getSheetByName("POTemplate");
// POTemplate range size
// I prefer not having ranges in A1 notation when I'm going to iterate
var tplFRow = 22, tplLRow = tplSheet.getLastRow();
var tplRowsNum = tplLRow - tplFRow + 1;
var tplFCol = 1, tplLCol = 16;
var tplColsNum = tplLCol - tplFCol + 1;
// Get all data at once: less getValue() calls, much faster
var rangeData = tplSheet.getRange(22, 1, tplRowsNum, tplColsNum).getValues();
// Column indexes to filter (A, D, K, M, P)
var colIndexes = [0, 3, 10, 12, 15];
var fData = filterByIndexes(rangeData, colIndexes);
var target = "POHistory";
var targetSheet = app.getActiveSpreadsheet().getSheetByName(target);
// Set size of destination range in POHistory sheet
var tgtRow = targetSheet.getLastRow() + 1;
var tgtRowsNum = fData.length - tgtRow + 1;
var tgtCol = 1;
var tgtColsNum = fData[0].length - 1 + 1;
// Set all values at once
targetSheet.getRange(tgtRow, tgtCol, tgtRowsNum, tgtColsNum).setValues(fData);
}
// Function to extract only the columns you need
function filterByIndexes(twoDArr, indexArr) {
var fData = [];
// Transpose Array to get only the column needed
twoDArr = twoDArr.transpose();
for(var i=0; i<indexArr.length; i++) {
fData.push(twoDArr[indexArr[i]]);
}
// Transpose result Array
return fData.transpose();
}
// Prototype function to transpose a 2D Array
Array.prototype.transpose = function() {
var a = this,
w = a.length ? a.length : 0,
h = a[0] instanceof Array ? a[0].length : 0;
if (h === 0 || w === 0) {return [];}
var i, j, t = [];
for (i = 0; i < h; i++) {
t[i] = [];
for (j = 0; j < w; j++) {
t[i][j] = a[j][i];
}
}
return t;
};
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 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)
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;
}