0

Trying to shuffle the columns of the table.

Tried the below code, but it doesn't shuffle at all.

I need the first four options to be shuffled.

window.onload = function() {
  $("div.question_div").randomize("span.tdran");
};


(function($) {

  $.fn.randomize = function(tree, childElem) {
    return this.each(function() {
      var $this = $(this);
      if (tree) $this = $(this).find(tree);
      var unsortedElems = $this.children(childElem);
      var elems = unsortedElems.clone();

      elems.sort(function() {
        return (Math.round(Math.random()) - 0.5);
      });

      for (var i = 0; i < elems.length; i++)
        unsortedElems.eq(i).replaceWith(elems[i]);
    });
  };

})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Question 3
<div class="question_div">
  <table>
    <tr>
      <td colspan="4">
        <p>In a camp, there is a meal for 200 children or 120 men. If 150 children have taken the meal, how many men will be served with the remaining meal?</p>
      </td>
    </tr>
    <tr>
      <span class="tdran">
        <td><input type="radio" name="radio3" id="checka3" value="A"></td>
        <td><label for="checka3">
            <p>31</p>
          </label></td>
      </span>
      <span class="tdran">
        <td><input type="radio" name="radio3" id="checkb3" value="B"></td>
        <td><label for="checkb3">
            <p>30</p>
          </label></td>
      </span>
    </tr>
    <tr>
      <span class="tdran">
        <td><input type="radio" name="radio3" id="checkc3" value="C"></td>
        <td><label for="checkc3">
            <p>29</p>
          </label></td>
      </span>
      <span class="tdran">
        <td><input type="radio" name="radio3" id="checkd3" value="D"></td>
        <td><label for="checkd3">
            <p>35</p>
          </label></td>
      </span>
    </tr>
    <tr>
      <td><input type="radio" name="radio3" id="checke3" value="E"></td>
      <td><label for="checke3">
          <p>None of these</p>
        </label></td>
    </tr>
  </table>
</div>
<hr>
</br>

Trying to shuffle the columns of the table.

Tried the below code, but it doesn't shuffle at all.

I need the first four options to be shuffled.


Can I get an additional side note, that how can I remove spaces between two options and between radio button & value?

enter image description here

matthias_h
  • 11,356
  • 9
  • 22
  • 40
vipejo
  • 25
  • 7

1 Answers1

0

Your HTML markup isn't valid - it's not possible to wrap a <td> with a <span>, the only allowed child of a <tr> is a <td>. Though it's possible to change the order of table cells randomly, I suggest to using <div>s instead as it's a lot easier.

window.onload = function() {
  randomize();
};

function randomize() {
  let questions = $(".question_div");
  let divCollection = questions.find(".ran");
  let divs  = Array.from(divCollection);
  shuffleArray(divs);
  for (const div of divs) {
    questions.append(div);
  }
}

function shuffleArray(array) {
  for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
}
label {
  display: inline-block;
  margin-left: 5px;
}

.ran {
  float: left;
  width: 200px;
}

div:nth-child(even) {
  clear: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Question 3
<div class="question_div">
  <p>In a camp, there is a meal for 200 children or 120 men. If 150 children have taken the meal, how many men will be served with the remaining meal?</p>
  <div class="ran">
    <input type="radio" name="radio3" id="checka3" value="A">
    <label for="checka3">
      <p>31</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checkb3" value="B"><label for="checkb3">
      <p>30</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checkc3" value="C"><label for="checkc3">
      <p>29</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checkd3" value="D"><label for="checkd3">
      <p>35</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checke3" value="E"><label for="checke3">
      <p>None of these</p>
    </label>
  </div>
</div>

To get more distance between the columns, simply increase the width in the class .ran. Working Fiddle. I used this answer for my answer: Javascript: Shuffle table rows

Update: The proposed solution only works with one question. To handle more questions, I made following adjustments using each():

window.onload = function() {
  randomize();
};

function randomize() {
  let questions = $(".question_div");

  questions.each(function() {
    let divCollection = $(this).find(".ran");
    let divs = Array.from(divCollection);
    shuffleArray(divs);
    for (const div of divs) {
      $(this).append(div);
    }
  });


}

function shuffleArray(array) {
  for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
}
label {
  display: inline-block;
  margin-left: 5px;
}

.ran {
  float: left;
  width: 200px;
}

div.ran:nth-child(odd) {
  clear: left;
}
.question_div {
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="question_div">
<p>
Question 4
</p>
  <p>In a camp, there is a meal for 200 children or 120 men. If 150 children have taken the meal, how many men will be served with the remaining meal?</p>
  <div class="ran">
    <input type="radio" name="radio3" id="checka3" value="A">
    <label for="checka3">
      <p>31</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checkb3" value="B"><label for="checkb3">
      <p>30</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checkc3" value="C"><label for="checkc3">
      <p>29</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checkd3" value="D"><label for="checkd3">
      <p>35</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio3" id="checke3" value="E"><label for="checke3">
      <p>None of these</p>
    </label>
  </div>

</div>

<div class="question_div">
<p>
Question 4
</p>
<p>In a camp, there is a meal for 200 children or 120 men. If 150 children have taken the meal, how many men will be served with the remaining meal?</p>
  <div class="ran">
    <input type="radio" name="radio4" id="checka4" value="A">
    <label for="checka4">
      <p>31</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio4" id="checkb4" value="B"><label for="checkb4">
      <p>30</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio4" id="checkc4" value="C"><label for="checkc4">
      <p>29</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio4" id="checkd4" value="D"><label for="checkd4">
      <p>35</p>
    </label>
  </div>
  <div class="ran"><input type="radio" name="radio4" id="checke4" value="E"><label for="checke4">
      <p>None of these</p>
    </label>
  </div>

</div>
matthias_h
  • 11,356
  • 9
  • 22
  • 40
  • This is working when there is only one question. But not working accurately when there is more than 1 question. I tried: https://jsfiddle.net/640rp3nL/ – vipejo May 09 '20 at 13:12
  • Also, `div:nth-child(even) { clear: left; }` changes all other divs present in the file. – vipejo May 09 '20 at 13:25
  • @vipejo I've adjusted your Fiddle to work with more questions. I also adjusted the div:nth-child() selector to only affect divs with the class .ran so it shouldn't interfere with other divs on yourpage. https://jsfiddle.net/uo2p4emn/ – matthias_h May 09 '20 at 14:41
  • Thanks for the update this time it worked as wanted, going ahead in this code I decided to shuffle my questions too. For this, I tried: https://jsfiddle.net/po4udtgf/, and it worked, but the issue went there is my submit button, hr tag, & Question Numbering Title all are coming first. (Sorry for my English) (The page is not as described in the code. – vipejo May 09 '20 at 19:19
  • @vipejo I've adjusted your Fiddle here https://jsfiddle.net/hgxs65pc/1/ with an additional container to separate the questions together with their corresponding title. – matthias_h May 09 '20 at 19:34
  • 1
    @vipejo I've adjusted your Fiddle so the questions are not repeating anymore. https://jsfiddle.net/71db50rj/ – matthias_h May 10 '20 at 14:53
  • There's a small bug when questions are 4 or more than that. https://jsfiddle.net/tkfnoreu/ One title doesn't have a question and one has 2 questions – vipejo May 10 '20 at 15:39
  • 1
    @vipejo I'm not sure what caused this bug, but I've just rewritten the Fiddle and now it works fine: https://jsfiddle.net/roj83eg6/ – matthias_h May 10 '20 at 16:02