-1

this has been kind of a hard question to explain so i'll do my best..

basically, i have a raffle app (of sorts). i have a grid of images that are assigned names(captions) and are created dynamically using javascript. the end goal of it is to have each picture on a different spot on the grid with a different name every time a button is clicked. the names are captured from a textarea and stored into an array. for the most part, i have it working. my only issue is that when the button is clicked, the images and names do not random independent of each other. in other words, the images will move on the grid, but the names stay the same for each picture.

i merely just want to shuffle the p tags around. i know it's because my img and p tags are part of the same div, but i'm lost on how to do these separately while still keeping the grid form, otherwise things start going out of place. the grid uses bootstrap.

now this line in particular did sort of work for me:

tDisplay.getElementsByTagName("p") [Math.random() * tDisplay.children.length | 0].textContent = names[Math.random() * tDisplay.children.length | 0];

i know it's long and ugly, just rough draft, but my problem with this is that i do not want names appearing any different than they appear in the names array. so if i have a names array:

["jon", "tim", "tim", "bob", "sally"]

these 5 names should appear on the grid, with "tim" showing 2 times and the other names appearing once. the random line shown above was breaking this rule. as an example when i tested it, "bob" would show up multiple times when it is only in the array once, and "jon" would be left out. i would just like to shuffle.

here is my code for my button logic. there are 3 buttons and a text area. if the baseball or football button is clicked, it will display teams of the respective sport, and then theres the actual random button at the bottom. the img and the p tags are appending to a div (newDiv), which is then appended to the display div tDisplay. i've commented out lines that do not work.

//button logic
bGroup.addEventListener("click", function images(e) {

  if (e.target.id !== "random") {
    tDisplay.innerHTML = "";
for (var i = 0; i < names.length; i++) {
  var newDiv = document.createElement("div");
  var newImg = document.createElement("img");
  var userName = document.createElement("p");

  newDiv.className = "col-sm-3 col-md-3 col-lg-2"
  newDiv.appendChild(newImg);
  newDiv.appendChild(userName);
  userName.textContent = names[i];



  if (e.target.id === "baseball") {
    newImg.src = "images/baseball/team" + i + ".jpg";
  } else if (e.target.id === "football") {
    newImg.src = "images/football/team" + i + ".gif";
  }
  tDisplay.appendChild(newDiv);
};


} else {

for (var i = 0; i <= tDisplay.children.length; i++) {

  tDisplay.appendChild(tDisplay.children[Math.random() * tDisplay.children.length | 0] );
  //  tDisplay.appendChild(tDisplay.children[Math.random() * tDisplay.children.length | 0].lastChild.innerHTML = p[Math.random() * tDisplay.children.length | 0]);

  // tDisplay.getElementsByTagName("p") [Math.random() * tDisplay.children.length | 0].textContent = names[Math.random() * tDisplay.children.length | 0];
  // names[Math.random() * tDisplay.children.length | 0];
}
  }
});
user2247061
  • 313
  • 3
  • 12

1 Answers1

1

I think its easier to just redraw the whole thing instead of shuffling it. For that we need to shuffle the names array, then take a random image and prevent duplicates:

//a shuffle function taken from https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array
function shuffle(a) {
  for (let i = a.length; i; i--) {
    let j = Math.floor(Math.random() * i);
    [a[i - 1], a[j]] = [a[j], a[i - 1]];
  }
}
//a names array
var names = ["john","jack"];
//a number array
var numbers = Array.from({length:names.length}).map((_,i)=>i);

function update(){
//shuffle
shuffle(names);
shuffle(numbers);
tDisplay.innerHTML = "";
names.forEach(( name,i) => {
 var newDiv = document.createElement("div");
 var newImg = document.createElement("img");
 var userName = document.createElement("p");

 newDiv.className = "col-sm-3 col-md-3 col-lg-2"
 newDiv.appendChild(newImg);
 newDiv.appendChild(userName);
 userName.textContent = name;



  if (e.target.id === "baseball") {
    newImg.src = "images/baseball/team" + numbers[ i ] + ".jpg";
  } else if (e.target.id === "football") {
    newImg.src = "images/football/team" + numbers[ i ] + ".gif";
  }
  tDisplay.appendChild(newDiv);
});
}
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • thank you for your answer. i understand most of the code you have posted, but i am not too advanced yet but i'm curious what this line does as i've never seen yet: `//a number array var numbers = Array.from({length:names.length}).map((_,i)=>i);` – user2247061 Aug 22 '17 at 01:32
  • @user2247061 if names.lengrh is 5, itll create an array like [0,1,2,3,4] – Jonas Wilms Aug 22 '17 at 11:50