Randomly order options in questions

Would love ability to randomly sort the list of available questions in a multiple choice question. Best practice for surveys to avoid people always clicking the first item and it being the same in every case.

Since we can put in an option called “Other” as well, it would be ideal to also have a way to exempt some choices from the random sort.

Note that this can be implemented via our logic feature as well – we allow dynamically updating options, and you can rearrange them in a random order plus exempt certain options from being rearranged as well

Good to know… but Given surveys best practices are to usually randomize order, it would be awesome to also not require advanced logic for this and it be a straightforward option in the UI.

That said, I can try this logic suggestion to get unblocked for now. You could problaby guess that I was going to ask for an example how to do this :slight_smile:

My guess is we need to do this using the advanced logic but not sure how. Tee links in your help doc here seem to be broken as it’s pointing to the same section?

Thanks for flagging – link is fixed, and you can see an example here: https://docs.feathery.io/platform/build-forms/logic/advanced/examples/randomize-field-option-order

Thanks! I’m getting closer… but I’d like to make the javascript I’m writing more generic. I noticed this in the rule builder:

is there a way to reference the current field that triggered the rule w/o explicitly specifying the name? I didn’t see it in the field or form properties in the docs. I expected to be able to call something like feathery.fields.getCurrentId() to then get the ID like this:

let currentFieldId = feathery.fields.getCurrentId();
let currentField = feathery.field[currentFieldId];
let currentFieldOptions = currentField.options;

currentField.options = shuffleArray(currentFieldOptions);

this way I could then have as many form steps trigger this… The way documented in help makes it hard to share code across multiple steps, when in this case is super helpful because the randomization is common. It also saves needing to chase updating field names in the javascript if you change field name in the UI–it would just auto follow whatever the current name is.

or am I thinking about this incorrectly and rules are always required to explicitly name the field names/IDs that they are operating on?

btw, the one downside of this is that if you got back and forth between steps, the order keeps changing. Is there some way to only do this randomization the first time a step is loaded and have the options stay in the last order?

I’m also encountering another issue. When we have a button group like this:

If I run a reordering on the field options, it becomes this and loses the images:

Is this a bug or is there another consideration to take into account for button groups when you reorder options?

yes, if you check out the options attribute doc here: https://docs.feathery.io/develop/context-api/field-object

You’ll see that there are additional attributes to switch over for option images and labels

I’m trying to figure out why this code doesn’t work. I’m missing something because the shuffleArray function shuffles the entire objects within the array, which means both the value and label properties (and any image property if present) are shuffled together. This maintains the association between the value and label within each option. I’m not sure why image wouldn’t be as well?

// define string to do a substring search on. All fields that match will be randomized
const fieldNameSearch = '1111where_selling_currently';
const excludeLast = true;

// Utility function to randomize array elements, excluding the last if specified
function shuffleArray(array, excludeLast) {
  const newArray = [...array];
  const limit = excludeLast ? newArray.length - 2 : newArray.length - 1;
  for (let i = limit; i >= 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
  }
  return newArray;
}

// Find and shuffle options for fields that include the substring in their name
Object.keys(feathery.fields).forEach(key => {
  if (key.includes(fieldNameSearch)) {
    const field = feathery.fields[key];
    if (field.options && Array.isArray(field.options)) {
      field.options = shuffleArray(field.options, excludeLast);
    }
  }
});

Thank you for flagging! You’re right, and we made an update to resolve this. If your forms are embedded, please use version 2.0.230