Sources

Miscellaneous sources

Google Sites and Forms sources

Due to the limitations of Google Sites and Google Forms, we cannot share the source of the site itself nor the sources of the forms without allowing anyone to edit them. So, if you would like a copy of the site's source or any of the Google Forms sources, please email us and we will create a copy for you.

Google Apps Script sources

Due to the limitations of container-bound Google Apps Scripts, we cannot share the projects. However, we can share the source code and triggers needed to construct the project.

Submodule 1.2 personality quiz results selector

function doGet() {

  return HtmlService.createHtmlOutputFromFile('index').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

}


function processForm(formObject) {

  var dateTime = formObject.myDateTime;

  var personalID = formObject.myID;

  return getResult(dateTime, personalID);

}


function getResult(resultDateTime, personalID)

{

  timeZone = new Date().getTimezoneOffset();

  resultDateTime = Utilities.formatDate(new Date(resultDateTime), timeZone, "yyyy-MM-dd'T'HH:mm");

  personalID = Utilities.computeDigest(

    Utilities.DigestAlgorithm.SHA_256, resultDateTime + personalID, Utilities.Charset.US_ASCII

  ).toString();


  var results = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1tUj-T4RQG7aYVDXs9JFto7Tkr5MuLMh4JvKNLO0CLkI/edit#gid=0').getActiveSheet().getDataRange().getValues();

  var asyncPercent;

  var syncPercent;

  var hybridPercent;

  for (var i = 1; i < results.length; i++)

  {

    thisDateTime = Utilities.formatDate(new Date(results[i][0]), 'UTC', "yyyy-MM-dd'T'HH:mm");


    if (thisDateTime == resultDateTime && results[i][2] == personalID)

    {

      asyncPercent = results[i][3];

      syncPercent = results[i][4];

      hybridPercent = results[i][5];


      return (

        '<p>Here are the probabilities that each course type is best for you. '

        + 'Note that these are not based on your likelihood of academic success, '

        + 'but instead, your likelihood of enjoyment and getting something out of each course type.</p>'

        + '<dl>'

        +   '<div>'

        +     '<dt>Asynchronous course</dt><dd>' + asyncPercent * 100 + '%</dd>'

        +   '</div>'

        +   '<div>'

        +     '<dt>Synchronous course</dt><dd>' + syncPercent * 100 + '%</dd>'

        +   '</div>'

        +   '<div>'

        +     '<dt>Hybrid course</dt><dd>' + hybridPercent * 100 + '%</dd>'

        +   '</div>'

        + '</dl>'

      );

    }

  }

  return '<p>Result not found. Check your input and try again.</p>';

}

Submodule 1.2 personality quiz (Print version)

Triggers:

function myFunction()

{

  const H1_STYLE =

  {

    [DocumentApp.Attribute.FONT_FAMILY]: 'Noto Sans',

    [DocumentApp.Attribute.FOREGROUND_COLOR]: '#0041A5',

    [DocumentApp.Attribute.BOLD]: true,

    [DocumentApp.Attribute.FONT_SIZE]: 18

  };

  const H2_STYLE =

  {

    [DocumentApp.Attribute.FONT_FAMILY]: 'Noto Sans',

    [DocumentApp.Attribute.FOREGROUND_COLOR]: '#000000',

    [DocumentApp.Attribute.FONT_SIZE]: 18

  };

  const H3_STYLE =

  {

    [DocumentApp.Attribute.FONT_FAMILY]: 'Noto Sans',

    [DocumentApp.Attribute.FOREGROUND_COLOR]: '#000000',

    [DocumentApp.Attribute.FONT_SIZE]: 14

  };

  const P_STYLE =

  {

    [DocumentApp.Attribute.FONT_FAMILY]: 'Noto Sans',

    [DocumentApp.Attribute.FOREGROUND_COLOR]: '#000000',

    [DocumentApp.Attribute.FONT_SIZE]: 12

  };

  const SMALL_STYLE =

  {

    [DocumentApp.Attribute.FONT_FAMILY]: 'Noto Sans',

    [DocumentApp.Attribute.FOREGROUND_COLOR]: '#000000',

    [DocumentApp.Attribute.FONT_SIZE]: 10

  }


  var doc = DocumentApp.getActiveDocument();

  var body = doc.getBody().clear();

  // "Submodule 1.2 personality quiz"

  var form = FormApp.openByUrl("https://docs.google.com/forms/d/1DuE8avUXLJWhN9xziPvryVM-dlvVrzF0Pske3NDsm40/edit");

  // "Submodule 1.2 personality quiz total points (auto updated - don't edit)"

  var sheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1Zh4O6tzMoPD1h1Uggu-M-RcHcXRRiua0pf9v9q-KP58/edit#gid=0").getActiveSheet();

  var asyncWeight = sheet.getRange("A1").getValue();

  // grab values for each category from the auto generated sheet

  var syncWeight = sheet.getRange("S1").getValue();

  var hybridWeight = sheet.getRange("H1").getValue();


  body.getChild(0).setText(form.getTitle());

  // Title of the original form that's used as reference

  body.getChild(0).setHeading(DocumentApp.ParagraphHeading.HEADING1).setAttributes(H1_STYLE);

  // people get confused so need a back link

  body.appendParagraph(

    "This version has opened in a new tab. To go back to the site, close this tab."

  ).setAttributes(SMALL_STYLE);

  // Grab heading from the document  maybe use doc var here instead? 

  body.appendParagraph("Questions").setHeading(DocumentApp.ParagraphHeading.HEADING2).setAttributes(H2_STYLE);

  var questions = form.getItems(FormApp.ItemType.GRID);

  var points = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);

  for (var i = 0; i < questions.length; i++)

  {

    // Questions \\

    // handle "(Select all that apply)"

    if (questions[i].getTitle().endsWith("(Select all that apply)"))

    {

      var qTitle = questions[i].getTitle().replace("(Select all that apply)", "");

      var selectN = "Select all that apply";

    }

    else

    {

      var qTitle = questions[i].getTitle();

      var selectN = "Select one";

    }


    body.appendParagraph(qTitle).setHeading(DocumentApp.ParagraphHeading.HEADING3).setAttributes(H3_STYLE);

    body.appendParagraph(selectN).setAttributes(SMALL_STYLE);


    var question = questions[i].asGridItem();

    var rows = question.getRows();

    var rowPoints = points[i].asMultipleChoiceItem().getChoices();

    for (var j = 0; j < rows.length; j++)

    {

      // Question Answers \\


      /*Possible Scores Letter Translate

        0               None

        1               H

        100             S

        101             SH

        10000           A

        10001           AH

        10100           AS

        10101           AHS

      */


      var asyncPoints = Math.floor(rowPoints[j].getValue() / 10000);

      var syncPoints = Math.floor((rowPoints[j].getValue() - (asyncPoints * 10000)) / 100);

      var hybridPoints = Math.floor((rowPoints[j].getValue() - (asyncPoints * 10000) - (syncPoints * 100) / 1));

      var thisAnsScore = "";


      if (asyncPoints != 0)

      {

        thisAnsScore = " (A)";

      }

      if (syncPoints != 0)

      {

        thisAnsScore = thisAnsScore + " (S)";

      }

      if (hybridPoints != 0)

      {

        thisAnsScore = thisAnsScore + " (H)";

      }


      body.appendListItem(

        rows[j] + thisAnsScore

      ).setGlyphType(

        DocumentApp.GlyphType.HOLLOW_BULLET

      ).setAttributes(

        P_STYLE

      );

    }

  }

  body.appendParagraph("Results").setHeading(DocumentApp.ParagraphHeading.HEADING2).setAttributes(H2_STYLE);

  //body.appendParagraph("").setAttributes(P_STYLE);

  body.appendParagraph("Write the number of answers you selected with an (A) at the end:  _______").setAttributes(P_STYLE);

  body.appendParagraph("Write the number of answers you selected with an (S) at the end:   _______").setAttributes(P_STYLE);

  body.appendParagraph("Write the number of answers you selected with an (H) at the end:  _______").setAttributes(P_STYLE);

  body.appendParagraph("").setAttributes(P_STYLE);

  body.appendParagraph("Asynchronous score (number of (A)s / " + asyncWeight + " × 100): _______%").setAttributes(P_STYLE);

  body.appendParagraph("Synchronous score (number of (S)s / " + syncWeight + " × 100):   _______%").setAttributes(P_STYLE);

  body.appendParagraph("Hybrid score (number of (H)s / " + hybridWeight + " × 100):           _______%").setAttributes(P_STYLE);

  body.appendParagraph("").setAttributes(P_STYLE);

  body.appendParagraph(

    "Note that these percentages are not based on your likelihood of academic success,"

    + " but instead, your likelihood of enjoyment and getting something out of each course type."

  ).setAttributes(P_STYLE);

  // body.clear() fails if last item is a list

  //body.appendParagraph("").setAttributes(P_STYLE);

  DocumentApp.getUi().alert('Document updated.');

}

Submodule 1.2 personality quiz (Responses)

Triggers:

function myFunction(e) {

  // auto-updated weights sheet

  var sheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1Zh4O6tzMoPD1h1Uggu-M-RcHcXRRiua0pf9v9q-KP58/edit#gid=0").getActiveSheet();

  // "Submodule 1.2 personality quiz (Public data)"

  var publicScores = SpreadsheetApp.openByUrl(

    'https://docs.google.com/spreadsheets/d/1tUj-T4RQG7aYVDXs9JFto7Tkr5MuLMh4JvKNLO0CLkI/edit#gid=0'

  ).getSheetByName('Sheet1');

  var score = e.values[2].split(" / "); // AASSHH / aasshh

  var points = parseFloat(score[0]);

  var weights = parseFloat(score[1]);


  var asyncPoints = Math.floor(points / 10000);

  var asyncWeight = Math.floor(weights / 10000);

  points = points - (asyncPoints * 10000);

  weights = weights - (asyncWeight * 10000);

  var syncPoints = Math.floor(points / 100);

  var syncWeight = Math.floor(weights / 100);

  points = points - (syncPoints * 100);

  weights = weights - (syncWeight * 100);

  var hybridPoints = Math.floor(points / 1);

  var hybridWeight = Math.floor(weights / 1);


  sheet.getRange("A1").setValue(asyncWeight);

  sheet.getRange("S1").setValue(syncWeight);

  sheet.getRange("H1").setValue(hybridWeight);


  asyncPercent = Math.round(asyncPoints / asyncWeight * 100) + "%";

  syncPercent = Math.round(syncPoints / syncWeight * 100) + "%";

  hybridPercent = Math.round(hybridPoints / hybridWeight * 100) + "%";


  // store result in publicScores spreadsheet

  var resultDateTime = Utilities.formatDate(new Date(e.values[25]), 'UTC', "yyyy-MM-dd'T'HH:mm");

  var resultTime = e.values[35];

  var personalID = e.values[36];

  // Salt and hash personalID for privacy reasons,

  // as publicScores is partially publicly accessible.

  // This does not need to be *as* secure as a password hash,

  // which is good because there's a monthly computation time limit for Apps Script.

  // We're going to use Sha256 because it's fast,

  // and because we're only even salting *just in case* the ID is personally identifiable information.

  personalID = Utilities.computeDigest(

    Utilities.DigestAlgorithm.SHA_256, resultDateTime + personalID, Utilities.Charset.US_ASCII

  ).toString();

  publicScores.appendRow(

    [

      resultDateTime,

      resultTime,

      personalID,

      asyncPercent,

      syncPercent,

      hybridPercent

    ]

  );

  /*

  htmlBody = "<p>Here are the probabilities that each course type is best for you. "

           + "Note that these are not based on your likelihood of academic success, "

           + "but instead, your likelihood of enjoyment and getting something out of each course type.</p>"

           + "<table><tr><th style=\"text-align: right;\">Asynchronous course: </th><td>"

           + asyncPercent + "</td></tr><tr><th style=\"text-align: right;\">Synchronous course: </th><td>"

           + syncPercent + "</td></tr><tr><th style=\"text-align: right;\">Hybrid course: </th><td>"

           + hybridPercent + "</td></tr></table>";

  textBody = "Here are the probabilities that each course type is best for you. "

           + "Note that these are not based on your likelihood of academic success, "

           + "but instead, your likelihood of enjoyment and getting something out of each course type.\n\n"

           + "\tAsynchronous course: " + asyncPercent + "\n"

           + "\tSynchronous course: " + syncPercent + "\n"

           + "\tHybrid course: " + hybridPercent + "\n";

  

  MailApp.sendEmail({

    to: email,

    name: "Online Readiness",

    replyTo: "northeastregionalconsortium@gmail.com",

    subject: "[Online Readiness] Lesson 1.2 Quiz Results",

    htmlBody: htmlBody,

    body: textBody

  });

  //GmailApp.sendEmail(email, "[Online Readiness] Lesson 1.2 Quiz Results", textBody);

  */

}