I have a huge spreadsheet matrix, from which I create a long list of check boxes. The users then select different abilities, press search. The code the cross-checks with the database spreadsheet, returning names of the persons who has those abilities.
I need to update the "rightPanel" with the results of my search. But i simple can't figure out how to - if at all posible - update a panel in my UI..
var dataSSkey = 'sheetID'; //datasheet ID
var dataSheet = SpreadsheetApp.openById(dataSSkey).getSheetByName('Ansatte');
var groupsArray = [[],[],[],[]];
var lastRow = dataSheet.getLastRow();
var lastColumn = dataSheet.getLastColumn();
var dataArray = dataSheet.getRange(1,1,lastRow,lastColumn).getValues();
var numberGroups
var app = UiApp.createApplication().setTitle('Find Consultant');
var panel = app.createVerticalPanel();
var leftPanel = app.createVerticalPanel().setWidth(450);
var rightPanel = app.createVerticalPanel().setWidth(450);
var grid = app.createGrid(1, 2).setId('myGrid')
var outputArray = []; //to store output from search
var positiveList = [[],[]]; //array to store name and folder-ID of consultants matching
var numberPositive = 0; //number of consultants matching
function doGet() {
buildGroupsArray()
addCheckBoxesToUI()
var scrollPanel = app.createScrollPanel().setHeight(460);
//Search button
var searchButton = app.createButton('Search');
var clickHandler = app.createServerClickHandler("respondToSearch");
searchButton.addClickHandler(clickHandler);
clickHandler.addCallbackElement(panel);
var spacerImage = app.createImage("http://www.bi..ge.jpg").setHeight(3);
scrollPanel.add(panel);
rightPanel.add(app.createLabel('resultat her'));
leftPanel.add(scrollPanel);
leftPanel.add(spacerImage);
leftPanel.add(searchButton);
grid.setWidget(0, 0, leftPanel)
grid.setWidget(0, 1, rightPanel);
app.add(grid);
return app;
}
function respondToSearch(e){
var numberLogged = 0;
//define firstEmpty
var firstEmpty = "A"+lastRow;
if(lastRow !== 1){
firstEmpty = "A"+(lastRow+1);
};
//find selected competencies --> store in array + count competencies
for(i = 1; i <= lastRow; i++){
if (e.parameter["Checkbox"+i] == "true") {
var value = e.parameter["CheckboxValue"+i];
outputArray[numberLogged] = value;
numberLogged++;
}
}
for(i = 2; i <= lastColumn; i++){
var numberCorrect = 0;
//Run through rows according to content of output from selection
for(j in outputArray){
//Check if consultant own selected competency
if(dataArray[outputArray[j]][i] == "x"){
numberCorrect++; //if consultant owns selected competency then count
}
}
//if consultant owns all competencies, then add name and folder-id to array
if(numberCorrect == numberLogged){
positiveList[0][numberPositive] = dataArray[1][i]; //Add consultant name
positiveList[1][numberPositive] = dataArray[2][i]; //Add consultant-folder ID
numberPositive++ //count the number of consultants that own all competencies
}
}
for(j in positiveList[0]){
var name = positiveList[0][j];
var id = positiveList[1][j];
Logger.log(name);
Logger.log(id)
var anchor = app.createAnchor(name,'https://ww......folderviewid='+id);
rightPanel.add(anchor)
}
return app;
}
I don't really understand the problem you have...
In your handler function you only have to use app=UiApp.getActiveApplication() and from there populate the panel exactly the same way you did it in the doGet() function, ending with a return app; that will actually update the current Ui.
There are dozens of examples all around... did I misunderstand something in your question ?
Edit : following your comment.
I suppose you defined your variables outside of the doGet function hoping they will become global and so available to all the functions in your script but this is not going to work. Global variables in Google Apps script can't be updated by functions.
I would strongly recommend that you create app and panels in the doGet function and give them an ID so that you can get them back and update their values (or content) from the handler functions.
Here is a re-written version of your code (didn't test)
: (some parts are not reproduced (see //...)
var dataSSkey = 'sheetID'; //datasheet ID
var dataSheet = SpreadsheetApp.openById(dataSSkey).getSheetByName('Ansatte');
var groupsArray = [[],[],[],[]];
var lastRow = dataSheet.getLastRow();
var lastColumn = dataSheet.getLastColumn();
var dataArray = dataSheet.getRange(1,1,lastRow,lastColumn).getValues();
var numberGroups
var outputArray = []; //to store output from search
var positiveList = [[],[]]; //array to store name and folder-ID of consultants matching
var numberPositive = 0; //number of consultants matching
function doGet() {
var app = UiApp.createApplication().setTitle('Find Consultant');
var panel = app.createVerticalPanel();
var leftPanel = app.createVerticalPanel().setWidth(450).setId('leftPanel');
var rightPanel = app.createVerticalPanel().setWidth(450).setId('rightPanel');;
var grid = app.createGrid(1, 2).setId('myGrid')
buildGroupsArray(app); // in this function get app as parameter or use UiApp.getActiveApplication();
addCheckBoxesToUI(app);// in this function get app as parameter or use UiApp.getActiveApplication();
var scrollPanel = app.createScrollPanel().setHeight(460);
//...
//...
return app;
}
function respondToSearch(e){
//...
//...
var app = UiApp.getActiveApplication();
var rightPanel = app.getElementById('rightPanel');
for(j in positiveList[0]){
var name = positiveList[0][j];
var id = positiveList[1][j];
Logger.log(name);
Logger.log(id)
var anchor = app.createAnchor(name,'https://ww......folderviewid='+id);
rightPanel.add(anchor)
}
return app;
}
Related
What I am trying to do is: I have a list, with N being a date and O being a checkbox. I need to get the rows which =N < Today() && O=False, then return A:B of those corresponding rows. I've tried it every which way, and I can't get it to work. Any suggestions?
function msg1(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var wscl = ss.getSheetByName('Connection List');
var contact = wscl.getRange("A2:B").getValues();
var msg1date = wscl.getRange("N2:N").getValues();
var msg1sent = wscl.getRange("O2:O").getValues();
var MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
var now = new Date();
var yesterday = new Date(now.getTime() - MILLIS_PER_DAY);
for(var i=0;i<msg1sent.length;i++){
if(msg1sent =="FALSE"&& msg1date < yesterday){
var row=i+1;
}
}
}
If you use getValues() of a checkbox it returns true or false booleans. If you use getDisplayValues() it returns "TRUE" or "FALSE" strings. And for the dates I just used valueOf() but you can also use getTime(). The easiest way to figure all of this out is to create some intermediate temporary variables and view them in the Script Debugger and you can see all of the return values there.
function msg1(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Connection List');
var ct=sh.getRange(2,1,sh.getLastRow()-1,2).getValues();
var date=sh.getRange(2,14,sh.getLastRow()-1,1).getValues();//date
var sent=sh.getRange(2,15,sh.getLastRow()-1,1).getValues();//checkbox
var dt=new Date();
var rows=[];
var today=new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();//0000 or midnight
for(var i=0;i<sent.length;i++){
var t1=sent[i][0];
var t2=new Date(date[i][0]).valueOf();
var t3=today;
if(sent[i][0]==false && new Date(date[i][0]).valueOf()<today){
rows.push(ct[i]);
}
}
Logger.log(rows);
}
If you use getDisplayValues() then it would look like this:
function msg1(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Connection List');
var ct=sh.getRange(2,1,sh.getLastRow()-1,2).getValues();
var date=sh.getRange(2,14,sh.getLastRow()-1,1).getValues();//date
var sent=sh.getRange(2,15,sh.getLastRow()-1,1).getDisplayValues();//checkbox
var dt=new Date();
var rows=[];
var today=new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();
for(var i=0;i<sent.length;i++){
var t1=sent[i][0];
var t2=new Date(date[i][0]).valueOf();
var t3=today;
if(sent[i][0]=="FALSE" && new Date(date[i][0]).valueOf()<today){
rows.push(ct[i]);
}
}
Logger.log(rows);
}
Currently this code copies every row and not the ones that match my criteria
I had some issues getting it to loop. Hence the loggers.
I'm quite new to this.
function searchAnotherSheetAndReturnRows(){
Logger.clear()
var tss = SpreadsheetApp.openById('1dX5MMLXGsG_S_KzRhOcquOp00VhzRBSlTCkyw'); // tss = target spreadsheet
var ts = tss.getSheetByName('Sheet1'); // ts = target sheet
var sss = SpreadsheetApp.openById('1ImDswr6ADS7t4HKIFHpntykN2LS7Mmd-cls34'); // sss = source spreadsheet
var ss = sss.getSheetByName('Page1'); // ss = source sheet
var tslast_row = ts.getLastRow();
var i=0;
Logger.log(i)
for (var i = 1; i < tslast_row; i++) {
Logger.log(i)
Logger.log(tslast_row);
var ssSearch1 = ss.getRange(2,1).getValue();
Logger.log(ssSearch1);
var tsSearch1 = ts.getRange(i,1).getValue();
Logger.log(tsSearch1);
if (ssSearch1 == tsSearch1); {
var tsSearch1Range = ts.getRange(i,1,1,7);
Logger.log(tsSearch1Range);
var range2Copy = tsSearch1Range.getValues();// Copies data from root sheet
Logger.log(range2Copy);
var last_row = ss.getLastRow();
Logger.log(last_row);
var last_row = last_row+1;
Logger.log(last_row);
ss.getRange(last_row,1,1,7).setValues(range2Copy);// Adds root sheet data to target
}
}
}
It's really hard to figure out what you're trying to do. So here's an example that will hopefully help you a little. The job of this function is to copy rows in the AlaskanWilderness that contain GOLD to MyPocket. (Names of Sheets)
function moveGoldFromAlaskanWildernessToMyPocket() {
var tss=SpreadsheetApp.openById('id');
var ts=tss.getSheetByName('MyPocket');
var sss=SpreadsheetApp.openById('id');
var ss=sss.getSheetByName('AlaskanWildernes');
var sr=ss.getDataRange()
var sd=sr.getValues();
var criteria='GOLD';
for (var i=1;i<sd.length;i++) {//skip header
for(var j=0;j<sd[i].length;i++) {
if (sd[i][j]=='GOLD'); {
ss.appendRow(sd[i]);
}
}
}
}
sheet.appendRow
range.getValues
I'm creating a social media outreach tracker. I want to create a drop-down list of the contact name. The problem is that I have two sources of names on two different sheets.
I wrote a script that pulls the names from the two different sources and combines them to a single array.
I was hoping to set the source range as that array.
Here is my code:
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.build();
range.setDataValidation(rule);
}
function onEdit() {
var auditionsSheet = SpreadsheetApp.getActiveSpreadsheet();
var castingDirectorsTab = auditionsSheet.getSheetByName("Casting Directors");
var contactsTab = auditionsSheet.getSheetByName("Contacts");
var socialMediaOutreachTab = auditionsSheet.getSheetByName("Social Media Outreach");
var lastRowCD = castingDirectorsTab.getLastRow();
var lastRowContacts = contactsTab.getLastRow();
var activeCell = socialMediaOutreachTab.getActiveCell();
var activeColumn = activeCell.getColumn();
// get data
var castingDirectorNameData = castingDirectorsTab.getRange(2, 1, lastRowCD, 1).getValues();
var contactNameData = contactsTab.getRange(2, 1, lastRowContacts, 1).getValues();
//get name data to a single arrays
var castingDirectorName = [];
castingDirectorNameData.forEach(function(yr) {
castingDirectorName.push(yr[0]);
});
var contactName = [];
contactNameData.forEach(function(yr) {
contactName.push(yr[0]);
});
// get rid of the empty bits in the arrays
for (var x = castingDirectorName.length-1; x > 0; x--) {
if ( castingDirectorName[x][0] === undefined ) {
castingDirectorName.splice( x, 1 )
}
}
for (var x = contactName.length-1; x > 0; x--) {
if ( contactName[x][0] === undefined ) {
contactName.splice( x, 1 )
}
}
//combine two data sources for data validation
var combinedNames = [];
combinedNames.push(castingDirectorName + contactName);
Logger.log (combinedNames);
Logger.log( typeof combinedNames);
// data validation set up and build
if (activeColumn == 1 && auditionsSheet.getName() == "Social Media Outreach") {
var range = auditionsSheet.getRange(activeCell.getRow(), activeColumn +1);
var sourceRange = combinedNames;
setDataValid_(range, sourceRange)
}
}
When I enter a date in Col A on Social Media Outreach, nothing happens in Col 2.
I was using an existing working nested data validation script I have but the sourceRange pulls from a sheet based on the value in the active cell. Here is that code:
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.build();
range.setDataValidation(rule);
}
function onEdit() {
var aSheet = SpreadsheetApp.getActiveSheet();
var aCell = aSheet.getActiveCell();
var aColumn = aCell.getColumn();
// data validation for Auditions Tab Projet Type to Project Details
if (aColumn == 9 && aSheet.getName() == 'Auditions') {
var range = aSheet.getRange(aCell.getRow(), aColumn + 1);
var sourceRange = SpreadsheetApp.getActiveSpreadsheet().getRangeByName('RefTables!' + aCell.getValue())
setDataValid_(range, sourceRange)
}
}
For this script when I select from the data validation drop-down, a new data validation comes up in the next col with the appropriate secondary data validation.
So the question is, can the source range be set to an array or do I need to put the names back into my sheet to reference a la the second script.
I've looked through the documentation and searched and can't find an answer. I'm relatively new to GAS and am not sure of all the inner workings of the data validation builder.
I've built a simple Student Information platform using Google Sheets. It allows the user to query, update and create new student info on a user interface. Please refer to this sheet to see how it works.
The functions to Refresh/Update/Save are inside the Actions button on a menu bar. Everything seems to work well however when the number of records increases, say above 100 records, all the functions slow down and it gets extremely slow with 200+ records.
Appreciate if anyone could help to take a look at the scripts as I suspect they need to be optimized.
Many thanks in advance!
function UpdateDataIntoMaster() { //This script is used in the SAVE button in UPDATE sheet)
/*Get data from UPDATE Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheet = ss.getSheetByName('UPDATE');
var range = sheet.getRange("D30:AE30"); //All data transposed into this line. MUST be updated if more fields are added into the Data sheet
var values = range.getValues();
var rangeForKey = sheet.getRange("D30") //Student Name is used as the
key identifier
var keyValue = rangeForKey.getValue();
/*Pass in keyValue(identifier = Student Name)
and all data in the function below in order
to update master data sheet*/
updDbase(keyValue,values);
function updDbase(keyValue,values) {
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY")
var sheet = ss.getSheetByName('Data');
var data = sheet.getDataRange().getValues();
var noOfRow = values.length
var noOfCol = values[0].length
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = ss.getSheetByName("Data").getRange(i+1,1).getValue(); //Get the Student Name from Data sheet
if (keyData == keyValue) {
// for (var j=0; j < data[i].length; j++) { // this is going through all the cell of a row
var row = Number(i)+1;
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Update Information","Are you sure you want to update the student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES)
{
var sheets = ss.getSheetByName("Data").getRange(row,1,noOfRow,noOfCol).setValues(values);
}//If response == YES
}
}
}
}
function CreateNew() {
/*Get data from Inquiry Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheetNew = ss.getSheetByName('Create New');
var range = sheetNew.getRange("D30:AZE30"); //All data transposed into
this line
var values = range.getValues();
var rangeForKey = sheetNew.getRange("E30") //Using Student ID as key identifier
var keyValue = rangeForKey.getValue();
var noOfRow = values.length
var noOfCol = values[0].length
var sheetData = ss.getSheetByName('Data');
var lastRow = sheetData.getLastRow();
var data = sheetData.getDataRange().getValues();
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = sheetData.getRange(i+1,2).getValue(); //Get the Student ID from Data sheet
if (keyData == keyValue) {
AlertBox();//If Student ID is found, to prompt Student ID already
exist
return;
} //If
} //For
/*Confirming with user whether to proceed to create new entry*/
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Create New Record","Are you sure you want to
create new student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES){
if (keyValue == ""){
var response = sh.alert("Create New Record","Unable to proceed
because Student ID is empty", sh.ButtonSet.OK);
return;}
else {
//var response = sh.alert("Create New Record","Unable to
proceed because Student ID is empty", sh.ButtonSet.OK);
var sheets =
sheetData.getRange(lastRow+1,1,1,noOfCol).setValues(values)
}
}//If
}
function EditStudentInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Inquiry");
//var ss = SpreadsheetApp.getActive();
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
}
}
}
function EditContent() {
var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Update");
var rangeContentCol1 = s.getRange("E3:E23");
var CopyContentCol1 = s.getRange("E3:E23").getValues();
var rangeContentCol2 = s.getRange("I3:I23");
var CopyContentCol2 = s.getRange("I3:I23").getValues();
rangeContentCol1.clearContent();
rangeContentCol2.clearContent();
var PasteContentCol1 =
s.getRange("E3:E23").setValues(CopyContentCol1);
var PasteContentCol2 = s.getRange("I3:I23").setValues(CopyContentCol2);
}
A common performance mistake people with Apps Script is doing the .getRange().getValues() within their for loops. Performance-wise these get and set calls are quite expensive.
Lucky the fix for this is quite easy - get all the data at once first, then loops through it. You actually do this already, sort of. In your script you get the whole data range, but then only use a part of the data and instead do another getValues call. I've updated the two areas in your script that had getRange() calls in a for loop --> var keyData = data[i][0];
function UpdateDataIntoMaster() { //This script is used in the SAVE button in UPDATE sheet)
/*Get data from UPDATE Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheet = ss.getSheetByName('UPDATE');
var range = sheet.getRange("D30:AE30"); //All data transposed into this line. MUST be updated if more fields are added into the Data sheet
var values = range.getValues();
var rangeForKey = sheet.getRange("D30") //Student Name is used as the
key identifier
var keyValue = rangeForKey.getValue();
/*Pass in keyValue(identifier = Student Name)
and all data in the function below in order
to update master data sheet*/
updDbase(keyValue,values);
function updDbase(keyValue,values) {
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY")
var sheet = ss.getSheetByName('Data');
var data = sheet.getDataRange().getValues();
var noOfRow = values.length
var noOfCol = values[0].length
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = data[i][0]; //Use the data that is already loaded.
if (keyData == keyValue) {
// for (var j=0; j < data[i].length; j++) { // this is going through all the cell of a row
var row = Number(i)+1;
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Update Information","Are you sure you want to update the student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES)
{
var sheets = ss.getSheetByName("Data").getRange(row,1,noOfRow,noOfCol).setValues(values);
}//If response == YES
}
}
}
}
function CreateNew() {
/*Get data from Inquiry Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheetNew = ss.getSheetByName('Create New');
var range = sheetNew.getRange("D30:AZE30"); //All data transposed into
this line
var values = range.getValues();
var rangeForKey = sheetNew.getRange("E30") //Using Student ID as key identifier
var keyValue = rangeForKey.getValue();
var noOfRow = values.length
var noOfCol = values[0].length
var sheetData = ss.getSheetByName('Data');
var lastRow = sheetData.getLastRow();
var data = sheetData.getDataRange().getValues();
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = data[i][0]; //Use the data that is already loaded.
if (keyData == keyValue) {
AlertBox();//If Student ID is found, to prompt Student ID already
exist
return;
} //If
} //For
/*Confirming with user whether to proceed to create new entry*/
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Create New Record","Are you sure you want to
create new student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES){
if (keyValue == ""){
var response = sh.alert("Create New Record","Unable to proceed
because Student ID is empty", sh.ButtonSet.OK);
return;}
else {
//var response = sh.alert("Create New Record","Unable to
proceed because Student ID is empty", sh.ButtonSet.OK);
var sheets =
sheetData.getRange(lastRow+1,1,1,noOfCol).setValues(values)
}
}//If
}
function EditStudentInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Inquiry");
//var ss = SpreadsheetApp.getActive();
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
}
}
}
function EditContent() {
var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Update");
var rangeContentCol1 = s.getRange("E3:E23");
var CopyContentCol1 = s.getRange("E3:E23").getValues();
var rangeContentCol2 = s.getRange("I3:I23");
var CopyContentCol2 = s.getRange("I3:I23").getValues();
rangeContentCol1.clearContent();
rangeContentCol2.clearContent();
var PasteContentCol1 =
s.getRange("E3:E23").setValues(CopyContentCol1);
var PasteContentCol2 = s.getRange("I3:I23").setValues(CopyContentCol2);
}
Give this a test and let me know if it helps!
I'm having a similar issue to this question - however I am requiring to get 2 e.parameters of both 1st and 2nd list boxes in order to populate the spreadsheet for the 3rd list box.
The vert is being read by the e.parameter, but the chan is undefined, which I do not understand as it is fully functional in the second list box but not the third.
Is there something that I have overseen in this code?
var channelBox = app.createListBox().setId('channelBox').setName('channelBox').setWidth(152).setHeight(22);
var chanHandler = app.createServerChangeHandler('showChannelinfo');
chanHandler.addCallbackElement(channelBox);
channelBox.addChangeHandler(chanHandler);
var chaArray = ['Select channel','--','Email','Phone','Chat']; for (var i=0;i<chaArray.length;++i) {channelBox.addItem(chaArray[i]);};
var verticalBox = app.createListBox().setId('verticalBox').setName('verticalBox').setWidth(152).setHeight(22);
var vertHandler = app.createServerChangeHandler('showVerticalinfo');
vertHandler.addCallbackElement(verticalBox);
verticalBox.addChangeHandler(vertHandler);
function showChannelinfo(e){
var app = UiApp.getActiveApplication();
var itemSpreadsheetKey = 'ABC------------123';
var openedSS = SpreadsheetApp.openById(itemSpreadsheetKey);
var sheetList3 = openedSS.getSheetByName("boolean3");//Vertical Lookup Sheet
var channelBox = app.getElementById('channelBox');
var verticalBox = app.getElementById('verticalBox');
var chan = e.parameter.channelBox;
if (chan == 'Phone')
{ verticalBox.clear();
var marketFilter = sheetList3.getRange('A1').setFormula('=iferror(filter(boolean2!A:D,boolean2!B:B=TRUE))');}
if (chan == 'Email')
{ verticalBox.clear();
var marketFilter = sheetList3.getRange('A1').setFormula('=iferror(filter(boolean2!A:D,boolean2!D:D=TRUE))');}
if (chan == 'Chat')
{ verticalBox.clear();
var marketFilter = sheetList3.getRange('A1').setFormula('=iferror(filter(boolean2!A:D,boolean2!C:C=TRUE))');}
var numItemList1 = sheetList3.getLastRow();//get the item array
var list1ItemArray = sheetList3.getRange(1,1,numItemList1).getValues();//Add the items in ListBox
for(var i=0; i<list1ItemArray.length; i++)
{verticalBox.addItem(list1ItemArray[i][0]);}
if (chan == '--')
{verticalBox.clear();
var vertArray = ['Select vertical','Hardware','Apps','Ebooks','Movies','Music','Nik','Shopping','Places','Wallet','YouTube','BeatThatQuote'];
for (var i=0;i<vertArray.length;++i) {verticalBox.addItem(vertArray[i]);};}
return app
};
function showVerticalinfo(e){
var app = UiApp.getActiveApplication();
var itemSpreadsheetKey = 'ABC------------123';
var openedSS = SpreadsheetApp.openById(itemSpreadsheetKey);
var sheetList4 = openedSS.getSheetByName("boolean4");//Language Lookup Sheet
var channelBox = app.getElementById('channelBox');
var verticalBox = app.getElementById('verticalBox');
var langBox = app.getElementById('langBox');
var chan = e.parameter.channelBox;
var vert = e.parameter.verticalBox;
langBox.clear();
var langFilter = sheetList4.getRange('A1').setFormula('=iferror(filter(boolean!A:D,boolean!A:A="' + chan + '",boolean!B:B="' + vert + '",boolean!D:D=TRUE))');
//**this returns as chan = undefined**
var numItemList2 = sheetList4.getLastRow();//get the item array
var list1ItemArray2 = sheetList4.getRange(1,3,numItemList2).getValues();//Add the items in ListBox
for(var i=0; i<list1ItemArray2.length; i++){langBox.addItem(list1ItemArray2[i][0]);}
if (chan == '--')
{langBox.clear();
var langArray = ['Select language','Dutch','French','German','Italian','Portuguese', 'Russian','Spanish'];
for (var i=0;i<langArray.length;++i) {langBox.addItem(langArray[i]);};}
return app
};
If anyone can use their magic eyes to give me any advice, it would be greatly appreciated!
The problem is with your callbackElement.
What I suggest is that you put both these list boxes into a single panel and add this panel as the callback element to both the handlers. Something like
function doGet(){
/* Your other code here */
var panel = app.createVerticalPanel().setId('panel');
var channelBox = app.createListBox().setId('channelBox').setName('channelBox').setWidth(152).setHeight(22);
var chanHandler = app.createServerChangeHandler('showChannelinfo');
chanHandler.addCallbackElement(panel); /* Add panel as the callback element */
channelBox.addChangeHandler(chanHandler);
var chaArray = ['Select channel','--','Email','Phone','Chat']; for (var i=0;i<chaArray.length;++i) {channelBox.addItem(chaArray[i]);};
var verticalBox = app.createListBox().setId('verticalBox').setName('verticalBox').setWidth(152).setHeight(22);
var vertHandler = app.createServerChangeHandler('showVerticalinfo');
vertHandler.addCallbackElement(panel); /* Add panel as the callback element */
verticalBox.addChangeHandler(vertHandler);
panel.add(channelBox);
panel.add(verticalBox);
/* Your other UI Code here */
}