Skip to content

Instantly share code, notes, and snippets.

@fightingmonk
Created January 16, 2023 01:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fightingmonk/5feea0809e9ebaeec403be9aa61a9483 to your computer and use it in GitHub Desktop.
Save fightingmonk/5feea0809e9ebaeec403be9aa61a9483 to your computer and use it in GitHub Desktop.
Google form section shuffler

Google form section shuffler

Google Apps Script for randomizing the order that sections are presented in a Google Form

Note that this works by randomizing the transition rules between sections in the form every 5 minutes. As of January 2023 it doesn't appear there is a way to shuffle the section order when the form is loaded by a respondent.

Setup

  1. Create a Google Form
    • Add multiple sections and be sure to set the transition rule after each section to “Go to section x”
    • Get the form's document id from the url - this is the random numbers and letters in the url between /d/ and /edit. E.g. if the url is https://docs.google.com/forms/d/ABc431-62ABCDEF/edit then your document id is ABc431-62ABCDEF
  2. Create a new Google Apps Script and give the project a name
  3. Go to Editor
    • Paste the below code into the Code.gs file
    • Replace ABc431-62ABCDEF on line 2 with your form’s id
    • Save the code
    • Run the code, ensure it runs to completion without error
  4. Go to Triggers
    • Create a new Trigger
    • Function: randomizeSections
    • Event source: Time-driven
    • Type of time based trigger: Minutes timer
    • Minute interval: Every 5 minutes
    • Failure notification: Notify me immediately
  5. Go to Executions
    • Wait 5 minutes, refresh, ensure you see an execution with type Time-Driven and that the script shows status as Completed
function randomizeSections() {
  const  form = FormApp.openById('ABc431-62ABCDEF');
  const items = form.getItems()

  //
  // find all pagebreaks in the form
  // each pagebreak represents both the preceeding section end and the next section start
  //
  const pagebreaks = [];
  for (let i=0; i<items.length; i++) {
    const item = items[i];
    const itemType = item.getType().name();
    if (itemType === 'PAGE_BREAK') {
      const pb = item.asPageBreakItem();
      pagebreaks.push(pb);
    }
  }

  //
  // shuffle the order in which we want to present the question sections
  //
  const questionCount = pagebreaks.length - 1;
  const questionOrder = Array.from(Array(questionCount).keys());
  shuffle(questionOrder);
  console.log('Question order', questionOrder);

  //
  // Update the transitions between sections to reflect our shuffled order
  // by traversing the questions in desired order (like a linked list, not an indexed array)
  //
  pagebreaks[0].setGoToPage(pagebreaks[questionOrder[0]]);
  for (let transition=1; transition<questionCount; transition++) {
    pagebreaks[questionOrder[transition-1]+1].setGoToPage(pagebreaks[questionOrder[transition]]);
  }
  pagebreaks[questionOrder[questionCount-1]+1].setGoToPage(pagebreaks[questionCount]);
}

function shuffle(arr) {
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment