0

Thanks to the help of Serge insas, I've been creating a form with google apps script. It was working well until I started to set some persistant variables. First I started with persistant variables made of text (example var choice1 = 'Hello') and it was working just fine. But I've made it a little more complicated using functions to define my variables. Here is a simplified version of my code :

var choix1 = Math.floor((Math.random() * (33-13)) + 13);
var choix2 = Math.floor((Math.random() * (66-33)) + 33);

function doGet() {
  var app = UiApp.createApplication().setTitle('test Questionnaire');
  var panel = app.createVerticalPanel();
  var sHdlr = app.createServerHandler('react').addCallbackElement(panel);
  var questions = ['<b>Question Numéro 1 :</b><br>Faites votre choix parmis les 4 possibilités suivantes','<b>Question 2</b><br>Encore un fois, faites votre choix','<b>Question 3</b><br>encore un effort...','<b>Question 4</b><br>vous y êtes presque...'];
  var Qitems = [[choix1.toString(),choix2.toString()],['choix1 de Q2','choix2 de Q2','choix3 de Q2','choix4 de Q2'],
  ['choix1 de Q3','choix2 de Q3','choix3 de Q3','choix4 de Q3'],['choix1 de Q4','choix2 de Q4','choix3 de Q4','choix4 de Q4']];
  var Qpanel = [];
  for (var n=0 ; n<questions.length ; ++n){
    var Qval = app.createTextBox().setId('Qvalue'+n).setName('Qvalue'+n).setVisible(false);
    Qpanel[n] = app.createVerticalPanel().setId('QP'+n).setVisible(false).add(app.createHTML(questions[n])).add(Qval).setStyleAttribute('padding','10px');
    panel.add(Qpanel[n]);
    for(var q=0;q<Qitems[n].length;++q){
      var name = Qitems[n][q]
      var handler = app.createClientHandler().forTargets(Qval).setText(name);
      Qpanel[n].add(app.createRadioButton('radioButtonQ'+n,name).addClickHandler(handler).setId(name).addClickHandler(sHdlr));
    }
    }
    app.add(panel);
    Qpanel[0].setVisible(true);
    return app;
}

function react(e){
  var app = UiApp.getActiveApplication();
  var source = e.parameter.source;
  var answer = [];
  for(var n = 0; n < 4 ; ++n){
    answer[n] = e.parameter['Qvalue'+n];
    Logger.log('answer '+ (n+1) + ' = '+answer[n]+' source = '+source)
    }
      if(answer[0]==choix1||answer[0]==choix2){app.getElementById('QP'+1).setVisible(true)}
      if(answer[1]=='choix1 de Q2'||answer[1]=='choix3 de Q2'){app.getElementById('QP'+2).setVisible(true)}
      if(answer[2]=='choix1 de Q3'||answer[2]=='choix3 de Q3'){app.getElementById('QP'+3).setVisible(true)}
      if(answer[3]=='choix1 de Q4'){
      app.add(app.createHTML('YESSSSSSSSS ... !!<br>Vous avez réussi !<br> vos réponses sont les suivantes : '+answer.join('  +  ')).setStyleAttribute('padding','20px'))
      }
  return app;
}

In the more complexe code : my finals variables are aggregations of multiples "little" variable as the one presented here. I've made it this way to build up complex scenarios. And I want those scenarios to change for every single user of the form. (Am I clear ?) In this example, I can not pass on to the question number 2, as the condition "answer[0]==choix1" does not seem to work. I've looked around some other question, and my problem might come from the definition of my variable, and using ScriptDb may help, but I'm confused about the way to use it here.

I'll continue to investigate, but at this moment I'm stuck with this problem.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
Vincxente
  • 57
  • 1
  • 7

2 Answers2

1

You can only assign constants to global variables outside of the executed code. Instead of:

var choix1 = Math.floor((Math.random() * (33-13)) + 13);
var choix2 = Math.floor((Math.random() * (66-33)) + 33);

function doGet() {
  var app = UiApp.createApplication().setTitle('test Questionnaire');
...

write

var choix1;
var choix2;

function doGet() {
choix1 = Math.floor((Math.random() * (33-13)) + 13);
choix2 = Math.floor((Math.random() * (66-33)) + 33);
  var app = UiApp.createApplication().setTitle('test Questionnaire');
...

in fact you can drop the lines

var choix1;
var choix2;

as well, but it's a good idea to list all global variables in one place.

However, you have to be aware that the variables choix1 and choix2 are not persistent at all - only visible at global scope. The values will be recomputed for each call of the webapp code.

More explicit:

if (answer[0]==choix1||answer[0]==choix2) ...

is simply nonsense in a server handler as choix1 and choix2 will have other random values than whatever was set in the doGet.

If you need session variables you have to store them in the UiInstance. Use Hidden elements, that's why they were invented.

Taras
  • 1,023
  • 8
  • 17
  • Ok thanks Taras. From what I understood, I can't set anything other than constant variables in global scopes. But it seems that even when I set my variables in the doGet function, it doesn't work. The server Handler recomputes the variables each time it is called (and you said it to me). But i've tried to store it in a Database or in Cache, but I'm still finding nothing to solve the problem. I've looked upon session variables as you said, but I don't really understand how it works. – Vincxente Jun 27 '13 at 10:11
0

Well I found a way to do what I want to. I store the different options in a spreadsheet and add directly the propositions into the question. Answers are just 'option1', 'option2'... so I still can know which option was chosen.

function doGet() {
  var choix1 = Math.floor((Math.random() * (33-13)) + 13);
  var choix2 = Math.floor((Math.random() * (66-33)) + 33);
  var ss = SpreadsheetApp.openById('0ApJ8EJRunZt-dEtBU2dkQ0xrRzdTeVJhZXdaQnR3VEE');
  var sh = ss.getActiveSheet();
  var firstEmptyRow = sh.getLastRow() + 1;
  var app = UiApp.createApplication().setTitle('test Questionnaire');
  var panel = app.createVerticalPanel();
  var sHdlr = app.createServerHandler('react').addCallbackElement(panel);
  var questions = ['<b>Question Numéro 1 :</b><br>Faites votre choix parmis les 4 possibilités suivantes :<br>'+ choix1 + '<br>' +choix2,'<b>Question 2</b><br>Encore un fois, faites votre choix','<b>Question 3</b><br>encore un effort...','<b>Question 4</b><br>vous y êtes presque...'];
  var Qitems = [['option1','option2'],['choix1 de Q2','choix2 de Q2','choix3 de Q2','choix4 de Q2'],
  ['choix1 de Q3','choix2 de Q3','choix3 de Q3','choix4 de Q3'],['choix1 de Q4','choix2 de Q4','choix3 de Q4','choix4 de Q4']];
  var Qpanel = [];
  for (var n=0 ; n<questions.length ; ++n){
    var Qval = app.createTextBox().setId('Qvalue'+n).setName('Qvalue'+n).setVisible(false);
    Qpanel[n] = app.createVerticalPanel().setId('QP'+n).setVisible(false).add(app.createHTML(questions[n])).add(Qval).setStyleAttribute('padding','10px');
    panel.add(Qpanel[n]);
    for(var q=0;q<Qitems[n].length;++q){
      var name = Qitems[n][q]
      var handler = app.createClientHandler().forTargets(Qval).setText(name);
      Qpanel[n].add(app.createRadioButton('radioButtonQ'+n,name).addClickHandler(handler).setId(name).addClickHandler(sHdlr));
    }
    }
    app.add(panel);
    sh.getRange(firstEmptyRow,1,1,1).setValue(choix1);
    sh.getRange(firstEmptyRow,2,1,1).setValue(choix2);
    Qpanel[0].setVisible(true);
    return app;
}

function react(e){
  var app = UiApp.getActiveApplication();
  var source = e.parameter.source;
  var answer = [];
  
  
  for(var n = 0; n < 4 ; ++n){
    answer[n] = e.parameter['Qvalue'+n];
    Logger.log('answer '+ (n+1) + ' = '+answer[n]+' source = '+source)
    }
      if(answer[0]=='option1'||answer[0]=='option2'){app.getElementById('QP'+1).setVisible(true)}
      if(answer[1]=='choix1 de Q2'||answer[1]=='choix3 de Q2'){app.getElementById('QP'+2).setVisible(true)}
      if(answer[2]=='choix1 de Q3'||answer[2]=='choix3 de Q3'){app.getElementById('QP'+3).setVisible(true)}
      if(answer[3]=='choix1 de Q4'){
      app.add(app.createHTML('YESSSSSSSSS ... !!<br>Vous avez réussi !<br> vos réponses sont les suivantes : '+answer.join('  +  ')).setStyleAttribute('padding','20px'))
      }
  return app;
}
Rubén
  • 34,714
  • 9
  • 70
  • 166
Vincxente
  • 57
  • 1
  • 7