How to shuffle the vertical order of across different section labels?

Viewed 58

I have a large html document where each part is separated by <section> </section> labels, for example:

<!DOCTYPE html>
<html>
<body>
<section>
<h1>A file</h1>

<form action="/action_page.php">
  <p>Please select your gender:</p>
  <input type="radio" id="male" name="gender" value="male">
  <label for="male">Male</label><br>
  <input type="radio" id="female" name="gender" value="female">
  <label for="female">Female</label><br>
  <input type="radio" id="other" name="gender" value="other">
  <label for="other">Other</label>
</section>
  <br>  
<section>
  <p>Please select your age:</p>
  <input type="radio" id="age1" name="age" value="30">
  <label for="age1">0 - 30</label><br>
  <input type="radio" id="age2" name="age" value="60">
  <label for="age2">31 - 60</label><br>  
  <input type="radio" id="age3" name="age" value="100">
  <label for="age3">61 - 100</label><br><br>
</section>
  <input type="submit" value="Submit">
</form>

</body>
</html>

How can I randomly shuffle the order of the sections? that is, I would like to each time the user loads the page the order of the section randomly switch?

3 Answers

To sort randomly you can use the sort() method along with Math.random() to reorder the elements. Also note that your HTML would need to be changed slightly to make the logic simpler - primarily by adding a new div around the section elements to contain them, and also ensuring that the <form> element wraps all the section content. Try this:

let $container = $('.sections');
$container.find('section').sort((a, b) => Math.random() > 0.5 ? 1 : -1).prependTo($container);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="/action_page.php">
  <h1>A file</h1>
  <div class="sections">
    <section>
      <p>Please select your gender:</p>
      <input type="radio" id="male" name="gender" value="male">
      <label for="male">Male</label><br>
      <input type="radio" id="female" name="gender" value="female">
      <label for="female">Female</label><br>
      <input type="radio" id="other" name="gender" value="other">
      <label for="other">Other</label>
    </section>
    <section>
      <p>Please select your age:</p>
      <input type="radio" id="age1" name="age" value="30">
      <label for="age1">0 - 30</label><br>
      <input type="radio" id="age2" name="age" value="60">
      <label for="age2">31 - 60</label><br>
      <input type="radio" id="age3" name="age" value="100">
      <label for="age3">61 - 100</label><br><br>
    </section>
  </div>
  <input type="submit" value="Submit">
</form>

Here's a solution that does not use jquery.

  • Add unique ids to each section
  • make a list of ids and shuffle them up (I use Knuth shuffle)
  • traverse the shuffled array and:
    • remove the section belonging to the current id (could be anywhere in the current ordering)
    • prepend the section belonging to the current id to the html (this produces a random ordering)
<!DOCTYPE html>
<html>
   <body>
      <h1>A file</h1>
      <form action="/action_page.php" id="action-page-form">
         <section id="gender-section">
            <p>Please select your gender:</p>
            <input type="radio" id="male" name="gender" value="male">
            <label for="male">Male</label><br>
            <input type="radio" id="female" name="gender" value="female">
            <label for="female">Female</label><br>
            <input type="radio" id="other" name="gender" value="other">
            <label for="other">Other</label>
         </section>
         <section id="age-section">
            <p>Please select your age:</p>
            <input type="radio" id="age1" name="age" value="30">
            <label for="age1">0 - 30</label><br>
            <input type="radio" id="age2" name="age" value="60">
            <label for="age2">31 - 60</label><br>  
            <input type="radio" id="age3" name="age" value="100">
            <label for="age3">61 - 100</label><br>
         </section>
         <br>
         <input type="submit" value="Submit">
      </form>
   </body>
   <script>
      const sectionList = ["gender-section", "age-section"];
      
      // Fisher-Yates (aka Knuth) Shuffle
      function shuffle(array) {
        var currentIndex = array.length, temporaryValue, randomIndex;
      
        // While there remain elements to shuffle...
        while (0 !== currentIndex) {
      
          // Pick a remaining element...
          randomIndex = Math.floor(Math.random() * currentIndex);
          currentIndex -= 1;
      
          // And swap it with the current element.
          temporaryValue = array[currentIndex];
          array[currentIndex] = array[randomIndex];
          array[randomIndex] = temporaryValue;
        }
      
        return array;
      }
      
      shuffle(sectionList);
      
      var formElement = document.getElementById("action-page-form");
      
      sectionList.forEach(sectionId => {
          var thisSection = document.getElementById(sectionId)
          thisSection.remove();
          formElement.insertBefore(thisSection, formElement.childNodes[0]);
      })
   </script>
</html>

For Knuth Shuffle see: How to randomize (shuffle) a JavaScript array?

Here's the solution I came up with (while the question was still unanswered). I like the jQuery answer now already posted. But if you didn't want to use jQuery:

window.onload = () => {
    const sections = document.querySelectorAll('section');
    const form = document.querySelector('form');
    sections.forEach(el => form.removeChild(el));
    Array.from(Array(sections.length).keys()).sort(() => Math.random() - 0.5).forEach((el, i) => form.insertBefore(sections[el], form.childNodes[i]));
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Shuffle</title>
</head>
<body>
    <h1>A file</h1>
    <form action="/action_page.php">
        <section>
            <p>Please select your gender:</p>
            <input type="radio" id="male" name="gender" value="male">
            <label for="male">Male</label><br>
            <input type="radio" id="female" name="gender" value="female">
            <label for="female">Female</label><br>
            <input type="radio" id="other" name="gender" value="other">
            <label for="other">Other</label><br>
        </section>
        <section>
            <p>Please select your age:</p>
            <input type="radio" id="age1" name="age" value="30">
            <label for="age1">0 - 30</label><br>
            <input type="radio" id="age2" name="age" value="60">
            <label for="age2">31 - 60</label><br>
            <input type="radio" id="age3" name="age" value="100">
            <label for="age3">61 - 100</label><br>
        </section>
        <br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

Related