Karl_S
Karl_S

Reputation: 3554

Pass Object to Templated HTML

I have an object I wold like to pass to a templated HTML file. If I use a simple variable, all is fine, as these work: on the server side I have the following at the top of code.gs:

//Define this here globally so it is accessed in the HTML Template
    var passedFestival = ' ';
    var passedSID = ' ';
    var passedRID = 'FALSE';

in the HTML file I have:

<script>

  var passedFestival = '<?!= passedFestival ?>';
  var passedSID = '<?!= passedSID ?>';
  var passedRID = '<?!= passedRID ?>';

</script>

I can use these in later code and get the appropriate value. I want to also use an Object, which is the result of reading a couple rows from the spreadsheet, and basically results in the following outside any function, same as the other variables, above:

var testformOptions = [];
testformOptions['currencies'] = [{"currency":"CAD", "default":false, "defaultOption":"Interac", "paymentOptions":"Cheque|Credit Card|Interac|PayPal", "sheetrow":2}, {"currency":"USD", "default":true, "defaultOption":"PopMoney", "paymentOptions":"Cheque|Credit Card|PayPal|PopMoney", "sheetrow":3}];
testformOptions['meals'] = {"use":true, "required":false, "default":"Omnivore", "values":"Omnivore|Vegan"};

in the HTML file I can reference the object's individual values:

if ('<?!= testformOptions.currencyOptions.use ?>') {
  $("#currencies").show();
}

But I would rather copy the object over completely and reference it as part of the client side data. I have tried a few things, most of which I understand why they didn't work, but I thought this would:

var formOptions = jQuery.extend(true, {}, <?!= testformOptions?>;

I have tried saving the data to a variable as json, but that didn't work since I have single quotes and other special characters in my final object.

Is there any way to get an object passed into an object on the client side outside using google.script.run to pass it after loading? I am reading the spreadsheet data as part of the initial doGet so I figured it may be faster to use templated HTML and pass the object.

EDIT

Thanks to the reply, I have working code. The final sample reads as follows. Some items are left out to allow focusing on the important parts. Code.gs:

var passedSID = ' ';
var passedRID = 'FALSE';
function doGet(passed) {

  if(passed.parameter.rid && passed.parameter.msid){
    // A registration ID and Spreadsheet ID were passed so this is to edit an existing registration
    passedSID = passed.parameter.msid;
    passedRID = passed.parameter.rid;
    var registrationValues = getRegistrationValues(passedSID, passedRID);
  }
  else if(passed.parameter.msid){
    // A Spreadsheet ID was passed so this is to complete a new registration
    passedSID = passed.parameter.msid;
  }

  //get the form options from the appropriate spreadsheet file
  //getFormOptions() is from Tutorial: Simple Mail Merge
  //https://developers.google.com/apps-script/articles/mail_merge
  testformOptions = getFormOptions(passedSID);

  //Create the HTML template
  var template = HtmlService.createTemplateFromFile('Index');

  template.data = JSON.stringify(testformOptions);

  // Build and return HTML in IFRAME sandbox mode.
  return template.evaluate()
      .setTitle('Registration Form').setWidth(620).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

function include(filename) {
  return HtmlService.createTemplateFromFile(filename).evaluate()
      .getContent();
}

Index.html:

<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
<link href="https://fonts.googleapis.com/css?family=Raleway:100" rel="stylesheet">
<html>
  <body>
  <div id="mybody">
  <form>
   <!-- Boring form html -->
</form>
</div>
  </body>
</html>

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
    var formOptions = $.extend(true, {}, <?!= data ?>);
</script>

<!-- Use a templated HTML printing scriptlet to import JavaScript. -->
<?!= HtmlService.createHtmlOutputFromFile('jquery_cloneform_js').getContent(); ?>
<?!= include('JavaScript'); ?>

And in JavaScript.html:

<script>
  var passedSID = '<?!= passedSID ?>';
  var passedRID = '<?!= passedRID ?>';

  // use onload to call initialization after the document loads
  window.onload = setForm;
function setForm(){

  var optionArray = [];
  var defaultOption = '';

  if (formOptions.currencyOptions.use) {
    $("#currencies").show();
    //Set the options for the currency
    var options = formOptions.currencyOptions.values;
    defaultOption = formOptions.currencyOptions.defaultOption;
    optionArray =  options.split("|");
    setSelectOptions('regcurrency', optionArray, defaultOption);

    var options = formOptions.currencies[1].paymentOptions;
    defaultOption = formOptions.currencies[1].defaultOption;
    optionArray =  options.split("|");
    setSelectOptions('paymentMethod', optionArray, defaultOption);
  }
}

Upvotes: 2

Views: 1102

Answers (1)

Tanaike
Tanaike

Reputation: 201388

How about a following answer?

Modification points :

var testformOptions = [];
testformOptions['currencies'] = [{"currency":"CAD", "default":false, "defaultOption":"Interac", "paymentOptions":"Cheque|Credit Card|Interac|PayPal", "sheetrow":2}, {"currency":"USD", "default":true, "defaultOption":"PopMoney", "paymentOptions":"Cheque|Credit Card|PayPal|PopMoney", "sheetrow":3}];
testformOptions['meals'] = {"use":true, "required":false, "default":"Omnivore", "values":"Omnivore|Vegan"};
  1. About the above script, testformOptions is defined as an array. So testformOptions['currencies'] and testformOptions['meals'] cannot be imported. So please modify from var testformOptions = []; to var testformOptions = {};.

  2. When it passes the object, please use JSON.stringify().

The scripts reflected above modifications are as follows.

code.gs :

function doGet() {
  var testformOptions = {};
  testformOptions['currencies'] = [{"currency":"CAD", "default":false, "defaultOption":"Interac", "paymentOptions":"Cheque|Credit Card|Interac|PayPal", "sheetrow":2}, {"currency":"USD", "default":true, "defaultOption":"PopMoney", "paymentOptions":"Cheque|Credit Card|PayPal|PopMoney", "sheetrow":3}];
  testformOptions['meals'] = {"use":true, "required":false, "default":"Omnivore", "values":"Omnivore|Vegan"};

  var t = HtmlService.createTemplateFromFile('index');
  t.data = JSON.stringify(testformOptions);
  return t.evaluate();
}

index.html

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<p id="disp"></p>
<script>
    var data = $.extend(true, {}, <?!= data ?>);
    $('#disp').text(JSON.stringify(data));
</script>

Result :

{
  "currencies": [
    {
      "currency": "CAD",
      "default": false,
      "defaultOption": "Interac",
      "paymentOptions": "Cheque|Credit Card|Interac|PayPal",
      "sheetrow": 2
    },
    {
      "currency": "USD",
      "default": true,
      "defaultOption": "PopMoney",
      "paymentOptions": "Cheque|Credit Card|PayPal|PopMoney",
      "sheetrow": 3
    }
  ],
  "meals": {
    "use": true,
    "required": false,
    "default": "Omnivore",
    "values": "Omnivore|Vegan"
  }
}

If I misunderstand your question, I'm sorry.

Upvotes: 1

Related Questions