How To Allow Users to Review Answers before Submiting Form? - google-apps-script

I've built a form with UiApp to collect information from the user. It's rather complex with multiple panels and file uploads, so I would like to give the user the opportunity review their inputs before submitting. I was hoping to display their inputs on one final review panel that would then allow them to decide to edit the info and move back to a earlier panel to edit.
Following is the test script. The farthest I've gotten is getting it to return 'textBox' and not the value of the textBox. Is it possible to get the values while staying in the doGet portion of my script, or must I move to doPost to access the values?
What would be the work around you would suggest?
Thanks for any and all help!
function doGet(e){
var app = UiApp.createApplication();
var appPanel = app.createVerticalPanel();
var form = app.createFormPanel();
var panel1 = app.createHorizontalPanel();
var emailLabel = app.createLabel('Your Email');
var email = app.createTextBox().setName('email').setId('email');
app.add(form);
var button1 = app.createButton('Go to Review');
panel1.add(emailLabel);
panel1.add(email);
panel1.add(button1);
appPanel.add(panel1);
form.add(appPanel);
var panel2 = app.createHorizontalPanel().setVisible(false);
var reviewLabel = app.createLabel('Your Email:');
var reviewEmail = app.createLabel(email);
panel2.add(reviewLabel);
panel2.add(reviewEmail);
appPanel.add(panel2);
//
var reviewPageTwo = app.createClientHandler()
.forTargets(panel1).setVisible(false)
.forTargets(panel2).setVisible(true);
button1.addClickHandler(reviewPageTwo);
return app;
}
UPDATE 8.24.12
I'm including the resulting script. It includes the review function, the button to lead the user back to edit, and the submitButton to post it. (You will need to replace the spreadsheet ID for the post to work.)
Thank for the help all!
Martin
function doGet(e){
var app = UiApp.createApplication();
var appPanel = app.createVerticalPanel();
var form = app.createFormPanel();
var panel1 = app.createHorizontalPanel().setId('panel1');
var emailLabel = app.createLabel('Your Email');
var email = app.createTextBox().setName('email').setId('email');
var syncChangeHandler = app.createServerHandler('syncText').addCallbackElement(form);
app.add(form);
var button1 = app.createButton('Go to Review');
panel1.add(emailLabel);
panel1.add(email);
panel1.add(button1);
appPanel.add(panel1);
form.add(appPanel);
var panel2 = app.createHorizontalPanel().setId('panel2').setVisible(false);
var reviewGrid = app.createGrid(3,3).setId('reviewGrid');
var reviewEmail = app.createLabel().setId('reviewEmail');
var reviewLabel = app.createLabel('Your Email:');
var submitButton = app.createSubmitButton('Submit');
var button2 = app.createButton('Edit Response');
panel2.add(reviewLabel);
panel2.add(reviewEmail);
panel2.add(button2);
panel2.add(submitButton);
appPanel.add(panel2);
//
var editResponse = app.createClientHandler()
.forTargets(panel1).setVisible(true)
.forTargets(panel2).setVisible(false);
button1.addClickHandler(syncChangeHandler);
button2.addClickHandler(editResponse);
return app;
}
function syncChangeHandler(e){
var app = UiApp.getActiveApplication();
app.getElementById('reviewEmail').setText(e.parameter.email);
app.getElementById('panel1').setVisible(false);
app.getElementById('panel2').setVisible(true);
return app;
}
function doPost(e){
var ss = SpreadsheetApp.openById('*your spreadsheet id here*').getSheets()[0];
var range = ss.getRange(ss.getLastRow()+1, 1, 1,2);
var values = [[new Date(),e.parameter.email]];
range.setValues(values);
var app = UiApp.getActiveApplication();
var label = app.createLabel('Thank You!');
app.add(label);
return app;
}

You have your entire function inside doGet(). The doGet() function is executed when your UI is first loaded.
So,
var email = app.createTextBox().setName('email').setId('email');
actually resolves to a text box. When you do
var reviewEmail = app.createLabel(email);
you are trying to pass a text box as an argument to createLabel, which is not allowed. Therefore this won't work. You must handle the changes to the text box in a handler.
function doGet(){
var syncChangeHandler = app.createServerHandler('syncText').addCallbackElement(form);
var email = app.createTextBox().setName('email').setId('email');
...
var reviewEmail = app.createLabel().setId('reviewEmail');
...
}
function syncText(e){
var app = UiApp.getActiveAplication();
app.getElementById('reviewEmail').setText(e.parameter.email);
return app;
}

What Srik said is true (of course ;-)), you can't indeed assign a label this type of value... What I would do (since you work in a doGet/doPost structure) is to create a second button just aside of the submit button that triggers a handler to a 'review' function that populates all the corresponding textBoxes , listBoxes or whatever you have with the values coming from your main form (a sort of copy of it) in the review panel that you already have. To achieve this you will need to add the form as a callBackElement to the handler (which was not necessary with the doPost scheme).
Another option could be to add this handler to all the widgets separately with 'key up' triggers or 'Value change triggers' so that the review panel is always up to date in real time, in this case the 'review before submit panel' could be visible at any time without further action from the user other than make it eventually visible (although it could also be always visible). In this option the handler function would be more like a 'synchroniser'. I'm afraid you'll have some difficulties with file upload though (since this can only work in a doGet/doPost structure).

Related

Changing the content of a UI element with a button press

I have a Google UI App that is designed to assist entering data into a google spreadsheet where most of the rows are identical. To do so an UI panel is created and text fields are used for each column of the spreadsheet. With the push of a button these values are appended to the spreadsheet.
I would like the button to then clear the contents of a single text box and maintain the values of the others to allow for entry of the next nearly identical item. My attempts to do so have resulted in "Error encountered: Object does not allow properties to be added or changed."
I have included a simplified version below, the actual script has many text boxes but this simplified example also shares the problem.
function showNewEntryDialog() {
var app = UiApp.createApplication();
app.setTitle("Add Multiple Items");
var panel = app.createVerticalPanel();
var grid = app.createGrid(9,3);
var nameTextBox = app.createTextBox();
var serialTextBox = app.createTextBox();
nameTextBox.setName('nameTextBox').setId('nameTextBox');
serialTextBox.setName('serialTextBox').setId('serialTextBox');
var snButton = app.createButton('Add and New SN')
grid.setWidget(0,0,app.createLabel('Name'));
grid.setWidget(0,1,nameTextBox);
grid.setWidget(4,0,app.createLabel('Serial Number'));
grid.setWidget(4,1,serialTextBox);
grid.setWidget(4,2,snButton);
panel.add(grid);
var snClickHandler = app.createServerClickHandler("respondToButtonPress");
snButton.addClickHandler(snClickHandler);
snClickHandler.addCallbackElement(panel);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function respondToButtonPress(e) {
var app = UiApp.getActiveApplication();
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow([e.parameter.nameTextBox,
e.parameter.serialTextBox]);
app.getElementById('serialTextBox').setText('');
// Does nothing?
app.getElementById('serialTextBox').setValue='';
// Error:Object does not allow changes
}
How can a button change the contents of a text box in the UI panel? If it cannot, in what other way can I achieve the behavior I desire?
Bryan's answer is correct but you could do it more efficiently using a clientHandler in your main function like this :
function showNewEntryDialog() {
var app = UiApp.createApplication();
app.setTitle("Add Multiple Items");
var panel = app.createVerticalPanel();
var grid = app.createGrid(9,3);
var nameTextBox = app.createTextBox();
var serialTextBox = app.createTextBox();
nameTextBox.setName('nameTextBox').setId('nameTextBox');
serialTextBox.setName('serialTextBox').setId('serialTextBox');
var snButton = app.createButton('Add and New SN')
grid.setWidget(0,0,app.createLabel('Name'));
grid.setWidget(0,1,nameTextBox);
grid.setWidget(4,0,app.createLabel('Serial Number'));
grid.setWidget(4,1,serialTextBox);
grid.setWidget(4,2,snButton);
panel.add(grid);
// a clientHandler : ----------------------------------------------------------
var cHandler = app.createClientHandler().forTargets(serialTextBox).setText('');
//-----------------------------------------------------------------------------
var snClickHandler = app.createServerClickHandler("respondToButtonPress");
snButton.addClickHandler(snClickHandler).addClickHandler(cHandler);// you can have multiple handlers on the same widget
snClickHandler.addCallbackElement(panel);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function respondToButtonPress(e) {
var app = UiApp.getActiveApplication();
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow([e.parameter.nameTextBox,
e.parameter.serialTextBox]);
}
Think .setText() and .setValue() essentially do the same thing so really only need one or the other. Your .setValue='' is invalid. Should be .setValue(''). Need a return app; at the end too.

VLOOKUP style app script using UiApp and textBox form to reference a spreadsheet

I'm trying to create an app script to work inside a Google Site that has a search text box which is supposed to reference a Spreadsheet and spit out results from that search. The problem, I believe, exists in the second half of the code where I'm trying to reference the spreadsheet based on the text entered into the box provide by the code below.
function doGet(e) {
var doc = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE);
var app = UiApp.createApplication().setTitle('New app');
// Create the entry form, a 1 x 2 grid with text boxes for name, age, and city that is then added to a vertical panel
var grid = app.createGrid(1, 2);
grid.setWidget(0, 0, app.createLabel('Name:'));
grid.setWidget(0, 1, app.createTextBox().setName('userName').setId('userName'));
// Create a vertical panel and add the grid to the panel
var panel = app.createVerticalPanel();
panel.add(grid);
var buttonPanel = app.createHorizontalPanel();
var button = app.createButton('submit');
var submitHandler = app.createServerClickHandler('submit');
submitHandler.addCallbackElement(grid);
button.addClickHandler(submitHandler);
buttonPanel.add(button);
var closeButton = app.createButton('close');
var closeHandler = app.createServerClickHandler('close');
closeButton.addClickHandler(closeHandler);
buttonPanel.add(closeButton);
// Create label called statusLabel and make it invisible; add buttonPanel and statusLabel to the main display panel.
var statusLabel = app.createLabel().setId('status').setVisible(false);
panel.add(statusLabel);
panel.add(buttonPanel);
app.add(panel);
return app;
}
function close() {
var app = UiApp.getActiveApplication();
app.close();
return app;
}
The Problem exists in the code below. I'm trying to search the Spreadsheet using the text entered into the textBox. I'm not sure how to achieve this.
// function called when submit button is clicked
function submit(e) {
// Write the data in the text boxes back to the Spreadsheet
var cell = getValue(e.parameter.submit);
var doc = SpreadsheetApp.openById('SPREADSHEET_ID_GOES_HERE');
var ss = doc.getSheets()[0];
var lastRow = doc.getLastRow();
var data = ss.getRange(2, 1, 2, 4).getValues();
for(nn=0;nn<data.length;++nn){
if (data[nn][1]==cell){break} ;// if a match in column B is found, break the loop
}
// Make the status line visible and tell the user the possible actions
app.getElementById('status').setVisible(true).setText(data[nn][1]);
return app;
}​
When the form is submitted, your handler function submit(e) receives an event, e. If we log the value of it with Logger.log(Utilities.jsonStringify(e)); we'll see that looks like this:
{"parameter":
{
"clientY":"52",
"clientX":"16",
"eventType":"click",
"ctrl":"false",
"meta":"false",
"source":"u146139935837",
"button":"1",
"alt":"false",
"userName":"Lucy",
"screenY":"137",
"screenX":"16",
"shift":"false",
"y":"14",
"x":"12"
}
}
We can access the value of our input boxes by name, for example e.parameter.userName.
One other tweak, we need to get a value for app. Here's what your working handler looks like:
// function called when submit button is clicked
function submit(e) {
var app = UiApp.getActiveApplication();
Logger.log(Utilities.jsonStringify(e)); // Log the input parameter (temporary)
// Write the data in the text boxes back to the Spreadsheet
var cell = e.parameter.userName;
var doc = SpreadsheetApp.openById('SPREADSHEET-ID');
var ss = doc.getSheets()[0];
var lastRow = doc.getLastRow();
var data = ss.getRange(2, 1, 2, 4).getValues();
var result = "User not found";
for (nn = 0; nn < data.length; ++nn) {
if (data[nn][1] == cell) {
result = data[nn][1];
break
}; // if a match in column B is found, break the loop
}
// Make the status line visible and tell the user the possible actions
app.getElementById('status').setVisible(true).setText(result);
return app;
}

google apps script TextBox value not passed to e.parameter.TextBoxName

On the code below I am defining a TextBox with name and id. The button handler works fine but I am not been able to get the value entered on the TextBox. The msgBox shows up but the e.parameter.matchValue shows as undefined.
On other part of the app I have the same logic but with a ListBox and it works fine.
What am I doing wrong?
function chooseColumnValueToMatch() {
var app = UiApp.createApplication().setHeight(150).setWidth(250);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var columnName = ScriptProperties.getProperty("columnNameToMatch");
var h1Line = app.createHTML("<h2>Value to match "+columnName+":</h2>");
var textPara = app.createHTML("<p>Type the VALUE that the <b>"+columnName+"</b> column must match EXACTLY to send the message.</p>");
var selectionHandler = app.createServerHandler('chooseColumnValueToMatchSelectionHandler');
var valueInputBox = app.createTextBox()
.setTitle("Match value for "+columnName)
.setName("matchValue")
.setId("matchValue");
var submitBtn = app.createButton("Submit", selectionHandler);
app.add(h1Line)
.add(textPara)
.add(valueInputBox)
.add(submitBtn);
ss.show(app);
}
function chooseColumnValueToMatchSelectionHandler(e){
var app = UiApp.getActiveApplication();
var columnName = ScriptProperties.getProperty("columnNameToMatch");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var msg = e.parameter.matchValue;
Browser.msgBox("Value to match "+columnName+" column is:", msg, Browser.Buttons.OK);
return app;
}
You have to use the ServerHandler.addCallbackElement method. The following code demonstrates it. The method call "tells" GAS internals that the value of the widget pointed as the parameter should be passed to the handler.
If you have multiple widgets, which should be handled by the handler, then, instead of calling the addCallbackElement with every widget, is possible to place all controls to a panel and point only the panel as the addCallbackElement method parameter. The code in the point 4.4 of this tutorial shows this way.
function doGet(e) {
var app = UiApp.createApplication();
var valueInputBox = app.createTextBox()
.setTitle("Match value for XXX")
.setName("matchValue")
.setId("matchValue");
var selectionHandler = app.createServerHandler('chooseColumnValueToMatchSelectionHandler');
selectionHandler.addCallbackElement(valueInputBox);
var submitBtn = app.createButton("Submit", selectionHandler);
var output = app.createLabel().setId("output");
app.add(valueInputBox).add(submitBtn).add(output);
return app;
}
function chooseColumnValueToMatchSelectionHandler(e){
var app = UiApp.getActiveApplication();
var output = app.getElementById("output");
var msg = e.parameter.matchValue;
output.setText("Value to match XXXX column is: " + msg);
return app;
}
It seems that you forgot to add a callbackElement to your handler
you could try like this :
selectionHandler.addCallbackElement(valueInputBox)
right after the submitBtn definition

Is there a way to turn off Auto Fill for users when filling out a form?

I think this is a quick one for you, Folks:
I am collecting data in a UiApp built form, and using validation before enabling them to continue. My problem is that often auto-fill will have different format than what is required in my form (such as the state written out instead of a postal abbreviation). I think this may lead to confusion, so I would love to force the users to fill out each box by hand.
Is there a way to turn off the auto-fill function of browsers?
If I were to build in html, would it give me more control of this?
Thanks for the help~
Martin
NOTE: I am using the "ChangeHandler" as it will at least update the validator when autofill is used.
Here's an example code which is of the style I am using. It includes multiple field validation and a review panel. Relevant to my question, but also may be useful for those building forms.
function doGet(e){
var app = UiApp.createApplication().setTitle("Review and Validation");
var appPanel = app.createVerticalPanel();
var form = app.createFormPanel();
var panel1 = app.createGrid(4,5).setId('panel1');
var firstNameLabel = app.createLabel("First Name:");
var firstName = app.createTextBox().setName('firstName').setId('firstName');
var lastNameLabel = app.createLabel("Last Name:");
var lastName = app.createTextBox().setName('lastName').setId('lastName');
var emailLabel = app.createLabel('Your Email');
var email = app.createTextBox().setName('email').setId('email');
var button1 = app.createButton('Go to Review').setEnabled(false);
var info1 = app.createLabel("Please Enter First Name")
.setVisible(false)
.setStyleAttribute('color', 'red');
var info2 = app.createLabel("Please Enter Last Name")
.setVisible(false)
.setStyleAttribute('color', 'red');
var info3 = app.createLabel("Please Enter Email")
.setVisible(false)
.setStyleAttribute('color', 'red');
var syncChangeHandler = app.createServerHandler('syncText').addCallbackElement(form)
.validateLength(firstName, 2, 30).validateLength(lastName, 2, 30).validateEmail(email);
var onValidInput =
app.createClientHandler().validateLength(firstName,2,30).validateLength(lastName,2,30).validateEmail(email).forTargets(
button1).setEnabled(true);
var onInvalidInput1 =
app.createClientHandler().validateNotLength(firstName, 2, 30).forTargets(button1).setEnabled(false).forTargets(info1).setVisible(true);
var onValidInput1 =
app.createClientHandler().validateLength(firstName, 2, 30).forTargets(info1).setVisible(false);
var onInvalidInput2 =
app.createClientHandler().validateNotLength(lastName, 2, 30).forTargets(button1).setEnabled(false).forTargets(info2).setVisible(true);
var onValidInput2 =
app.createClientHandler().validateLength(lastName, 2, 30).forTargets(info2).setVisible(false);
var onInvalidInput3 =
app.createClientHandler().validateNotEmail(email).forTargets(button1).setEnabled(false).forTargets(info3).setVisible(true);
var onValidInput3 =
app.createClientHandler().validateEmail(email).forTargets(info3).setVisible(false);
firstName.addChangeHandler(onInvalidInput1);
firstName.addChangeHandler(onValidInput1);
lastName.addChangeHandler(onInvalidInput2);
lastName.addChangeHandler(onValidInput2);
email.addChangeHandler(onInvalidInput3);
email.addChangeHandler(onValidInput3);
firstName.addChangeHandler(onValidInput);
lastName.addChangeHandler(onValidInput);
email.addChangeHandler(onValidInput);
panel1.setWidget(0,0, firstNameLabel);
panel1.setWidget(0,1, firstName);
panel1.setWidget(0,2, lastNameLabel);
panel1.setWidget(0,3, lastName);
panel1.setWidget(1,1, info1);
panel1.setWidget(1,3, info2);
panel1.setWidget(2,0, emailLabel);
panel1.setWidget(2,1, email);
panel1.setWidget(2,3, button1);
panel1.setWidget(3,1, info3);
app.add(form);
appPanel.add(panel1);
form.add(appPanel);
var panel2 = app.createGrid(4,5).setId('panel2').setVisible(false);
var reviewFirstNameLabel = app.createLabel("First Name:");
var reviewFirstName = app.createLabel().setId('reviewFirstName');
var reviewLastNameLabel = app.createLabel("Last Name:");
var reviewLastName = app.createLabel().setId('reviewLastName');
var reviewEmailLabel = app.createLabel('Your Email:');
var reviewEmail = app.createLabel().setId('reviewEmail');
var submitButton = app.createSubmitButton('Submit');
var button2 = app.createButton('Edit Response');
panel2.setWidget(0,0, reviewFirstNameLabel);
panel2.setWidget(0,1, reviewFirstName);
panel2.setWidget(0,2, reviewLastNameLabel);
panel2.setWidget(0,3, reviewLastName);
panel2.setWidget(1,0, reviewEmailLabel);
panel2.setWidget(1,1, reviewEmail);
panel2.setWidget(2,0, button2);
panel2.setWidget(3,0, submitButton);
appPanel.add(panel2);
//
var editResponse = app.createClientHandler()
.forTargets(panel1).setVisible(true)
.forTargets(panel2).setVisible(false);
button1.addClickHandler(syncChangeHandler);
button2.addClickHandler(editResponse);
return app;
}
function syncText(e){
var app = UiApp.getActiveApplication();
app.getElementById('reviewFirstName').setText(e.parameter.firstName);
app.getElementById('reviewLastName').setText(e.parameter.lastName);
app.getElementById('reviewEmail').setText(e.parameter.email);
app.getElementById('panel1').setVisible(false);
app.getElementById('panel2').setVisible(true);
return app;
}
function doPost(e){
var ss = SpreadsheetApp.openById('0Aiapuj1KtAujdHYzZzNzMEsxMUtranZhaXhiSFFnanc').getSheets()[0];
var range = ss.getRange(ss.getLastRow()+1, 1, 1,4);
var values = [[new Date(),e.parameter.firstName, e.parameter.lastName, e.parameter.email]];
range.setValues(values);
var app = UiApp.getActiveApplication();
var label = app.createLabel('Thank You!');
app.add(label);
return app;
}
GAS is globally browser independent since the app is running on Google's Server and doesn't interact directly with your browser... I don't think it is possible to tell the browser to do anything like that and I haven't seen any trick that would make that possible... If I'm wrong then I'd be very curious about it ;-)
Edit : I played with your code and I was wondering if it might not be a solution to use a key press handler instead of click handler so users would be forced to use keyboard to fill the form instead of mouse click. I've seen scripts that check if an 'enter' was pressed to validate an answer. (just an idea)
EDIT 2 : Well, Browsers are too smart, I tested it but autocomplete simulates keypress quite efficiently... too bad :-/

How to know which Radio Button is selected?

I have 3 Radio buttons in my Ui in the same Radio group. They are,
var rbutton1 = app.createRadioButton('dist','5 miles');
var rbutton2 = app.createRadioButton('dist','10 miles');
var rbutton3 = app.createRadioButton('dist','25 miles');
In the event handler function, the variable, e.parameter.dist gives true or false just based on whether rbutton3 (the last radio button) is checked or not. Is there any way to determine what radio button is selected exactly?
The only way the make radio buttons group work like this (as intended by design) is by using them in a FormPanel and looking the name (in your case "dist") on a doPost from a submit action of the form.
There's some workarounds though, using the new client handlers that make it radio buttons usage on any panel roughly the same as on the from. Please take a look at this issue on the tracker. You may want to star this issue as well, to keep track of updates and kind of vote for it.
I use:
eventData.parameter.source
and pick up the change using addClickHandler.
You need to store this somewhere
Are these buttons suppose to be in an exclusive OR mode. If so, they need to have the same name. Look at Serge's answer for a detailed explanation and example code.
in the meantime I came up with a workaround to set the radiobutton as well, in this example I use a listBox but any other data could be used.
Here is the complete code : (to test in a spreadsheet container)
function radiotest() {
var app = UiApp.createApplication();
var panel = app.createVerticalPanel();
var radioValue = app.createTextBox().setId('radioValue');
radioValue.setId("radioValue").setName("radioValue");
var listhandler = app.createServerHandler('listhandler').addCallbackElement(panel);
var list = app.createListBox().addChangeHandler(listhandler).setName('list');
for(var i = 1; i < 10; i++){
var name = 'choice '+i;
list.addItem('Activate '+name,name)
var handler = app.createClientHandler().forTargets(radioValue).setText(name);
panel.add(app.createRadioButton('radioButtonGroup',name).addValueChangeHandler(handler).setId(name));
}
panel.add(radioValue);
var getit=app.createButton("Valide").setId("val");
panel.add(getit).add(list)
var handler = app.createServerHandler("valide")
handler.addCallbackElement(panel)
getit.addClickHandler(handler);
app.add(panel);
SpreadsheetApp.getActiveSpreadsheet().show(app);// show app
}
//
function valide(e){ ;// This function is called when key "validate" is pressed
var sh = SpreadsheetApp.getActiveSheet();
var RadioButton = e.parameter.radioValue;
sh.getRange('A1').setValue(RadioButton);
var app = UiApp.getActiveApplication();
return app;
}​
function listhandler(e){ ;// This function is called when listBox is changed
var sh = SpreadsheetApp.getActiveSheet();
var app = UiApp.getActiveApplication();
var listvalue = e.parameter.list
var radioValue = app.getElementById('radioValue').setValue(listvalue)
sh.getRange('A2').setValue(listvalue);
var radiobutton = app.getElementById(listvalue)
radiobutton.setValue(true)
return app;
}​
the selected radioButton values comes in the textBox value and the listBox allows to select which radioButton is activated... it shows up like this
There is also another approach, as stated by eddyparkinson that is to use the e.parameter.source but this works only if the handler is assigned directly to the radioButton and not using a 'submit' button. In many case it can be used and makes the code a(little) bit lighter.
Here is a test of this code
function radiotest2() {
var app = UiApp.createApplication();
var panel = app.createVerticalPanel();
var listhandler = app.createServerHandler('listhandler2').addCallbackElement(panel);
var list = app.createListBox().addChangeHandler(listhandler).setName('list');
var handler = app.createServerHandler("valide2")
handler.addCallbackElement(panel)
for(var i = 1; i < 10; i++){
var name = 'choice '+i;
list.addItem('Activate '+name,name)
panel.add(app.createRadioButton('radioButtonGroup',name).setId(name).addClickHandler(handler));
}
panel.add(list)
app.add(panel);
SpreadsheetApp.getActiveSpreadsheet().show(app);// show app
}
function valide2(e){ ;// This function is called when a radioButton is selected
var sh = SpreadsheetApp.getActiveSheet();
var source = e.parameter.source;
var radioValue = '';
if(source.match('choice')=='choice'){radioValue=source}
sh.getRange('A1').setValue(radioValue);
var app = UiApp.getActiveApplication();
return app;
}​
function listhandler2(e){ ;// This function is called when listBox is changed
var sh = SpreadsheetApp.getActiveSheet();
var app = UiApp.getActiveApplication();
var listvalue = e.parameter.list
sh.getRange('A2').setValue(listvalue);
var radiobutton = app.getElementById(listvalue)
radiobutton.setValue(true)
return app;
}​