Question

I am writing an application that pulls task data (for a task management system) from rows in a Google Spreadsheet with conditions matching a query. I then send this data into a flexTable next to a checkbox with an onClickHandler as well as a textbox to enter in hours data. Below is the simplest example of how I have achieved this:

\\establish handler for checkboxes that are generated in flexTable
var updateHandler = app.createServerClickHandler('updateTasksfunc');
updateHandler.addCallbackElement(taskTable);

\\search Google Spreadsheet for rows matching condition
for(var i=1; i< taskData.length; i++){
   if (taskData [i][1] !=employee){
     continue;      
   }

\\look up if task is already completed, and set checkbox value to true/false
var complete = taskData[i][8].toString();
if(complete==="true"){var checkbox=true;}else{var checkbox=false;}

\\populate flexTable with values from spreadsheet query
taskTable.setWidget(i,0,app.createTextBox().setName('hours'+i).setWidth('50').setId("hour"+i)).setWidget(i,1,app.createCheckBox().setValue(checkbox).setName('complete'+i).addClickHandler(updateHandler)).setWidget(i,2,app.createLabel(taskData[i][2]).setWidth('250')).setWidget(i,3,app.createLabel(taskData[i][3]).setWidth('250')).setWidget(i,4,app.createLabel(taskData[i][4])).setWidget(i,5,app.createLabel(taskData[i][5])).setWidget(i,6,app.createLabel(taskData[i][6])).setWidget(i,7,app.createLabel(taskData[i][7])).setWidget(i,8,app.createTextBox().setVisible(false).setName("dataRow"+i).setValue(i))
}

\edits to doGet()

var numberOfItems = app.createTextBox().setName('rows').setValue(i).setVisible(false);
var rows1 = i+1;
taskTable.setWidget(rows1,0,numberOfItems)

I have stored the spreadsheet data row in the invisible textbox in column 8 of the flex table that I intend to use in the clickHandler function to update the Google Spreadsheet.

I have successfully activated a click handler that runs when a checkbox is clicked; however, I have not yet successfully figured out a way to grab data from the flexTable that I can use to update the Spreadsheet.

//Functional code below

function updateTasksfunc(e){
  var app = UiApp.getActiveApplication();

  var taskSS = SpreadsheetApp.openById('SPREADSHEETID');
  var taskSH = taskSS.getSheets()[0];
  var taskData = taskSS.getDataRange().getValues();

  var results = [];// an array to collect results
  var numberOfItems = e.parameter.rows; 
  app.add(app.createLabel(numberOfItems));
  for(var n=0;n<numberOfItems;n++){
    results.push([e.parameter['check'+n]]);// each element is an array of 2 values
  }
  for(var i=1;i<results.length;i++){
    var check = results[i][0];
    var row = i+1;
    taskSH.getRange(row,9,1,1).setValue(check);
  }
return app;  
} 

I am getting a generic error: cannot find function getRowCount() from generic.

I assume that this means that I am not properly calling my flexTable.

Any thoughts??

Was it helpful?

Solution

flextables are not working like spreadsheets, you can't get widgets values directly as part of the table. You have to get every textBox and checkBox separately using e.parameter.Name.

You can do that easily in a loop but you'll have to know the number of textBoxes to be able to rebuild the names just as you did to create them in the doGet function.

I would suggest to store this number in a tag on one of your widget or in a separate hidden widget (hidden class or invisible textBox). Then you will be able to get the values like this :

...
var results = [];// an array to collect results
var numberOfItems = Number(e.parameter.itemNumbers); // this is the var you are missing right now and need to add. This is the solution of a separate hidden widget
for(var n=0;n<numberOfItems;n++){
  results.push([e.parameter['hours'+n],e.parameter['complete'+n]]);// each element is an array of 2 values
  }
... // from here you will have an 2D array with all your values and you can continue like you did=.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top