The description is simple: I have three checkboxes and the third one must select all the others when selected (and deselect them as well, once it's unchecked). All this must be in a grid, I can't use html or any other language but Google Apps Script.
This is probably a simple task for you, but I'm struggling a lot, both with javascript and english. Anyway here's the code:
function checkboxes() {
var range = SpreadsheetApp.getActiveSpreadsheet();
var sheet = range.getSheetId();
var myapp = UiApp.createApplication().setTitle('Title').setWidth(1000).setHeight(100);
var mygrid = myapp.createGrid(3, 3).setCellPadding(5).setCellSpacing(5);
//One
mygrid.setWidget(0, 0, myapp.createLabel('One').setId('One'));
mygrid.setWidget(0, 1, myapp.createCheckBox().setName('One'));
//Two
mygrid.setWidget(1, 0, myapp.createLabel('Two').setId('Two'));
mygrid.setWidget(1, 1, myapp.createCheckBox().setName('Two'));
var handler1 = myapp.createClientHandler().forTargets(myapp.getElementById('One')).setValue(true).forTargets(myapp.getElementById('Two')).setValue(true);
//Last
mygrid.setWidget(2, 0, myapp.createLabel('Last').setId('Last'));
mygrid.setWidget(2, 1, myapp.createCheckBox().setName('Last').OnClickHandler(handler1));
//...
}
Last time I tried it was not possible to use ClientHandlers validations with with checkboxes. So you have to stick with serverhandlers, which are slower, so you might need to add a little infinity progress gif so the user knows something is being done.
Here's an example of the solution I use:
function mygui() {
var imgUrl = 'https://f0839004-a-62cb3a1a-s-sites.googlegroups.com/site/hgabreu/files/ajax-loader.gif';
//I may remove this image from this url at any time. Host yours in a place you control
var app = UiApp.createApplication().setTitle('CheckAll example');
var panel = app.createVerticalPanel();
var boxes = ['Example 1', 'Test', 'Last check'];
var groupName = 'myCheckBoxes';
var groupAll = groupName+','+boxes.length;
var image = app.createImage(imgUrl).setId(groupName+',img').setVisible(false);
var checkAll = app.createCheckBox("Check All").setId(groupAll).setName(groupAll).addValueChangeHandler(
app.createServerHandler('checkAll_').addCallbackElement(panel)).addValueChangeHandler(
app.createClientHandler().forEventSource().setVisible(false).forTargets(image).setVisible(true));
panel.add(checkAll).add(image);
for( var i in boxes )
panel.add(app.createCheckBox(boxes[i]).setId(groupName+','+i));
SpreadsheetApp.getActive().show(app.add(panel));
}
function checkAll_(e) {
var app = UiApp.getActiveApplication();
var p = e.parameter; //just shortening
var checkState = p[p.source] == 'true';
var parts = p.source.split(',');
var groupName = parts[0];
var size = +parts[1];
for( var i = 0; i < size; ++i )
app.getElementById(groupName+','+i).setValue(checkState);
app.getElementById(groupName+',img').setVisible(false);
app.getElementById(p.source).setVisible(true);
return app;
}
Here is a possible workaround with client handler :(tested)
I personally find it easier and more clear to use variables for widget creation instead of having to get them by id... a few lines of code to write but easier to read ;-)
function checkboxes() {
var range = SpreadsheetApp.getActiveSpreadsheet();
var sheet = range.getSheetId();
var app = UiApp.createApplication().setTitle('Title').setWidth(200).setHeight(150);
var grid = app.createGrid(4, 3).setCellPadding(5).setCellSpacing(5);
//One
var one = app.createCheckBox().setName('One');
grid.setWidget(0, 0, app.createLabel('One').setId('One'));
grid.setWidget(0, 1, one);
//Two
var two = app.createCheckBox().setName('Two')
grid.setWidget(1, 0, app.createLabel('Two').setId('Two'));
grid.setWidget(1, 1, two);
//three
var three = app.createCheckBox().setName('Three')
grid.setWidget(2, 0, app.createLabel('Three').setId('Three'));
grid.setWidget(2, 1, three);
//...
var r1 = app.createRadioButton('radio').setHTML('All');
var r2 = app.createRadioButton('radio').setHTML('None');
grid.setWidget(3, 0, r1)
grid.setWidget(3, 1, r2)
var Chandler1 = app.createClientHandler().forTargets(one,two,three).setValue(true)
r1.addClickHandler(Chandler1)
var Chandler2 = app.createClientHandler().forTargets(one,two,three).setValue(false)
r2.addClickHandler(Chandler2)
app.add(grid)
var doc = SpreadsheetApp.getActive()
doc.show(app)
}
EDIT : following Henrique's comment (very clever !! thanks) here is a 'full checkBoxes' version that works just fine ;-)
function checkboxes2() {
var range = SpreadsheetApp.getActiveSpreadsheet();
var sheet = range.getSheetId();
var app = UiApp.createApplication().setTitle('checkBoxes test').setWidth(200).setHeight(150);
var grid = app.createGrid(4, 3).setCellPadding(5).setCellSpacing(5);
var one = app.createCheckBox().setName('One');
grid.setWidget(0, 0, app.createLabel('One').setId('One'));
grid.setWidget(0, 1, one);
var two = app.createCheckBox().setName('Two')
grid.setWidget(1, 0, app.createLabel('Two').setId('Two'));
grid.setWidget(1, 1, two);
var allP = app.createVerticalPanel()
var allA = app.createCheckBox().setName('allA');
var allB = app.createCheckBox().setName('allB').setVisible(false);
var allP = app.createVerticalPanel().add(allA).add(allB);
grid.setWidget(2, 0, app.createLabel('All').setId('all'));
grid.setWidget(2, 1, allP);
var ChandlerA = app.createClientHandler().forTargets(one,two,allB).setValue(true).forTargets(allB).setVisible(true).forEventSource().setVisible(false);
allA.addClickHandler(ChandlerA)
var ChandlerB = app.createClientHandler().forTargets(one,two,allA).setValue(false).forTargets(allA).setVisible(true).forEventSource().setVisible(false);
allB.addClickHandler(ChandlerB)
app.add(grid)
var doc = SpreadsheetApp.getActive()
doc.show(app)
}
Today I finally had the time to see your code, thanks for your support.
Like you said in your comment, I don't need the image at all, so I'm trying to take it out from the function mygui, let's see if I can do it:
function mygui() {
var app = UiApp.createApplication().setTitle('CheckAll example');
var panel = app.createVerticalPanel();
var boxes = ['Example 1', 'Test', 'Last check'];
var groupName = 'myCheckBoxes';
var groupAll = groupName+','+boxes.length;
var checkAll = app.createCheckBox("Check All").setId(groupAll).setName(groupAll).addValueChangeHandler(
app.createServerHandler('checkAll_').addCallbackElement(panel));
panel.add(checkAll);
for( var i in boxes )
panel.add(app.createCheckBox(boxes[i]).setId(groupName+','+i));
SpreadsheetApp.getActive().show(app.add(panel));
}
I have just cancelled line nr 2, 3 and 8 then I truncked line nr 9 and 10. That's enough for un unexpected mistake, standing to the error message.