1

My problem is that I want to select maybe 20 out of 100 checkboxes and then get 10 random out of the 20 selected.

I have already tried with Math.floor(Math.random() but without any luck, I cant figure out how to combine the two if it's possible at all

(This is my first question, hope you can help. Thanks)

function getValue() {
  var checks = document.getElementsByClassName('checks');
  var str = 'Selected = ' + '<br>';


  for (i = 0;
    [i] < checks.length; i++) {
    if (checks[i].checked === true) {
      str += checks[i].value + ", " + "<br>";
    }
  }
  document.getElementById("Selected").innerHTML = str + "end";
}
<button onclick="getValue()">Click me</button>
<div class="prøve">
  <div class="option">
    <input type="checkbox" class="checks" value="film & animation" />
    <label>Film & Animation</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="science" />
    <label>Science & Technology</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="art" />
    <label>Art</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="music" />
    <label>Music</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="travel" />
    <label>Travel & Events</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="sports" />
    <label>Sports</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="news" />
    <label>News & Politics</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="tutorials" />
    <label>Tutorials</label>
  </div>
</div>

<div id="Selected">All Selected</div>
connexo
  • 53,704
  • 14
  • 91
  • 128
Filur
  • 11
  • 2
  • `label` elements are supposed be tied to the element they describe. This can either be achieved by wrapping the input element with the label, or putting an `id` on the input and then add that id-value in the label's `for`-attribute. Also `[i] < checks.length` must be `i < checks.length`. – connexo Mar 28 '21 at 18:52

3 Answers3

0

Perhaps this ? I am using this shuffle https://stackoverflow.com/a/12646864/295783

const shuffleArray = array => { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array }; // https://stackoverflow.com/a/12646864/295783

const getValue = () => {
  const checks = [...document.querySelectorAll('.checks:checked')];
  if (checks.length > 0)
    document.getElementById("Selected").innerHTML = `Selected = <br>
      ${shuffleArray(checks)
        .slice(0,10).map(chk => chk.value).join(", ")}`;
}
document.getElementById("getVal").addEventListener("click", getValue)
<button id="getVal">Click me</button>
<div class="prøve">
  <div class="option">
    <input type="checkbox" class="checks" value="film & animation" />
    <label>Film & Animation</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="science" />
    <label>Science & Technology</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="art" />
    <label>Art</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="music" />
    <label>Music</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="travel" />
    <label>Travel & Events</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="sports" />
    <label>Sports</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="news" />
    <label>News & Politics</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="tutorials" />
    <label>Tutorials</label>
  </div>
</div>

<div id="Selected">All Selected</div>

One in each div

const shuffleArray = array => { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array }; // https://stackoverflow.com/a/12646864/295783

const getValue = () => {
  const checks = [...document.querySelectorAll('.checks:checked')];
  if (checks.length > 0) {
    const list = shuffleArray(checks).slice(0,10).map(chk => chk.value);
    document.getElementById("Selected").innerHTML = `Selected = <br>${list.join(", ")}`;
    list.forEach((val,i) => document.getElementById(`div${i}`).textContent = val);
  }  
}
document.getElementById("getVal").addEventListener("click", getValue)
<button id="getVal">Click me</button>
<div class="prøve">
  <div class="option">
    <input type="checkbox" class="checks" value="film & animation" />
    <label>Film & Animation</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="science" />
    <label>Science & Technology</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="art" />
    <label>Art</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="music" />
    <label>Music</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="travel" />
    <label>Travel & Events</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="sports" />
    <label>Sports</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="news" />
    <label>News & Politics</label>
  </div>

  <div class="option">
    <input type="checkbox" class="checks" value="tutorials" />
    <label>Tutorials</label>
  </div>
</div>

<div id="Selected">All Selected</div>
<div id="div0"></div>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
<div id="div5"></div>
<div id="div6"></div>
<div id="div7"></div>
<div id="div8"></div>
<div id="div9"></div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    That Works amazing, just what I was looking for fantastic. – Filur Mar 28 '21 at 19:26
  • Du er velkommen – mplungjan Mar 28 '21 at 19:45
  • I updated to add a join, to have neater separation between the values – mplungjan Mar 29 '21 at 05:03
  • do you have an idea on how to get the 10 random out on 10 various divs insted og the 10 random in 1 div as we currently have. So the same ramdom does not get repeated? – Filur Mar 30 '21 at 13:58
  • What I meen is if I wanted to get the 10 random displayed in 10 different divs. rigtht now we display the 10 random in the div with id Selected but what if I wanted to get 1 random in div with id Selected1 and then a new random in a new div with id Selected2 etc.? – Filur Mar 30 '21 at 14:25
  • You mean `${shuffleArray(checks).slice(0,10).map(chk => chk.value).forEach((val,i) => document.getElementById("div"+i).textContent=val);` – mplungjan Mar 30 '21 at 14:27
  • if (checks.length > 0) document.getElementById("Selected").innerHTML = `Selected =
    ${shuffleArray(checks).slice(0,10).map(chk => chk.value).forEach((val,i) => document.getElementById("Selected"+i).textContent=val)}`; ?
    – Filur Mar 30 '21 at 14:59
  • No. You need two separate statements. See second example – mplungjan Mar 30 '21 at 15:04
  • yeah i see, great. – Filur Mar 30 '21 at 15:10
0

This shuffleArray function will shuffle it and slice all checked inputs, in this demo to make an result of 3. change this number to your needs: arr.slice(0, 3);

function getValue() {
  let val = [...document.querySelectorAll('.checks:checked')].map(c => c.value)
  
  shuffleArray(val).forEach(e => document.getElementById("Selected").innerHTML += "<br>" + e)
}


function shuffleArray(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]];
  }
  return arr.slice(0, 3);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Checkbox</title>
</head>

<body>

  <button onclick="getValue()">Click me</button>
  <div class="prøve">
    <div class="option">
      <input type="checkbox" class="checks" value="film & animation" />
      <label>Film & Animation</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="science" />
      <label>Science & Technology</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="art" />
      <label>Art</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="music" />
      <label>Music</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="travel" />
      <label>Travel & Events</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="sports" />
      <label>Sports</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="news" />
      <label>News & Politics</label>
    </div>

    <div class="option">
      <input type="checkbox" class="checks" value="tutorials" />
      <label>Tutorials</label>
    </div>
  </div>

  <div id="Selected">All Selected</div>

</body>
<script src="Checkbox.js"></script>

</html>
ikiK
  • 6,328
  • 4
  • 20
  • 40
  • This is identical to my code except your DOM update is in a loop and you have c instead of chk – mplungjan Mar 29 '21 at 04:59
  • @mplungjan So identical but not identical ;) And there are more differences, and I like my better, its cleaner. Shuffle is the same yes, I just returned it sliced. – ikiK Mar 29 '21 at 12:44
0

See comments inline for details:

const randomAmount = 3; // How many do we want in the end?

let randoms = []; // Random checkbox references will go here
  
function getValue() {
  // Get all the selected checkboxes into a collection.
  // DO NOT use the legacy .getElementsByClassName() as it
  // returns a "live" node list that hinders performance.
  // Instead, use .querySelectorAll() and pass a selector that
  // gets you all checked checkboxes initially so you don't have
  // to loop and find them manually.
  var checks = document.querySelectorAll('.checks:checked');
  getRandoms(checks);  // Call out another function to get the randoms
  document.getElementById("Selected").textContent = randoms;
}

function getRandoms(checks){
  let gotThree = false;  // Starting value
  
  // Loop until you have 3 unique randoms
  while (!gotThree){
     // Get a random from 0 to 3
     let rnd = Math.floor(Math.random() * randomAmount); 
     
     // Is the random NOT already in the array?
     if(!randoms.includes(rnd)){
       // Add the checkbox that corresponds to that index
       randoms.push(checks[rnd]);
     }
     // Do we now have all the random checkboxes we wanted?
     if(randoms.length === randomAmount){
       gotThree = true;
       console.log(randoms);
     }
  }
}
<button onclick="getValue()">Click me</button>
<div class="prøve">
  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="film & animation">
    Film & Animation</label>
  </div>

  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="science">
    Science & Technology</label>
  </div>

  <div class="option">
      <label>
    <input type="checkbox" class="checks" value="art">
    Art</label>
  </div>

  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="music">
    Music</label>
  </div>

  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="travel">
    Travel & Events</label>
  </div>

  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="sports">
    Sports</label>
  </div>

  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="news">
    News & Politics</label>
  </div>

  <div class="option">
    <label>
    <input type="checkbox" class="checks" value="tutorials">
    Tutorials</label>
  </div>
</div>

<div id="Selected">All Selected</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71