Only returning part of an array item

Hi, anyone know what I’m doing wrong here?

Backstory: I run a charity sweepstake and I’m trying to bring in some automation. Players choose a driver for each Formula One race. My aim is to build a tool that reminds them who they’ve already chosen.

I’ve copied the list of player names in from a spreadsheet, using the TEXTJOIN function in Excel to turn it into a long string like this:
Adam Brown&Adam Smith&Alex Parker (and so on - there are 54 players)

Then I’ve used this JS code to turn that string into an array of names and set them as options in an HTML select element:

const players = playerListImport.split(‘&’);

let playerNameSelect = document.getElementById(‘playerNameSelect’);
let options = players.map(player => <option value=${player}>${player}</option>).join(‘\n’);
playerNameSelect.innerHTML = options;

That works fine, but the next step is to use the selected player name as a variable:

let playerName = playerNameSelect.value;

And when I do that, I just get the first name of the first player (‘Adam’), nomatter which player is selected in the HTML select.

I’m really confused - especially because I’ve checked that the array of players are all full names, and the full names are shown as option on the HTML select. Can anyone help?

Thanks!

Maybe the .value doesn’t work with spaces.
I guess you could do use the text instead of the value
let playerName = playerNameSelect.selectedOptions[0].textContent;
if you don’t want to use the .value

Also, you may need to use quotation marks for the value attribute:
value="${player}"

1 Like

That worked! Thank you so much!

Luckily we did have one player who I only have a first name for, so I’ve been able to continue using her to test everything out in the meantime. I’m getting somewhere with it now, I’ll post the code when I finish because I’m sure there are a lot of ways I could tidy it up.

I got it working :slight_smile: there are definitely improvements to be made and I’ll revisit as I learn more, so I’m not looking for help here (but feel free to offer advice :)), just posting in case anyone is interested.

//To be manually updated after each round - there's a better way (going through the choices array from one player name to the next and returning the items in between) but I couldn't work out how to do it yet
const racesCompleted = 5;

//Copied in from the Excel spreadsheet, where the TEXTJOIN formula turns it into one long string
//I've replaced the actual player names with some examples for privacy
const usedDriversImport = 'Adam Brown&Alonso&Gasly&Ocon&Sainz&Stroll&Adam Smith&Albon&Leclerc&Perez&Sainz&Verstappen&Alex Jones&Albon&Perez&Russell&Sainz&Stroll&John Doe&Alonso&Perez&Sargeant&Stroll&Verstappen&Jane Doe&Alonso&Bottas&Magnussen&Norris&Piastri'

//Also copied from Excel - the list of player names made into a string using TEXTJOIN for easy copying
const playerListImport = 'Adam Brown&Adam Smith&Alex Jones&John Doe&Jane Doe'

//Turns the string of player and their driver choices into an array
const choices = usedDriversImport.split('&');

//Turns the string of player names into an array and adds 'Choose player' as the first item in that array (solely so that 'Choose player' can be the default option shown in the select element - I know there will be a better way to do this
const players = playerListImport.split('&');
players.unshift('Choose player');

//Array of possible drivers, any substitutions to be added if necessary (that would cause other issues we'd have to fix)
const driverList = ['Albon', 'Alonso', 'Bottas', 'Gasly', 'Hamilton', 'Hulkenberg', 'Leclerc', 'Magnussen', 'Norris', 'Ocon', 'Perez', 'Piastri', 'Russell', 'Sainz', 'Sargeant', 'Stroll', 'Tsunoda', 'Verstappen', 'De Vries', 'Zhou'];

//Sets the player names as options in the 'Choose player' select element
let playerNameSelect = document.getElementById('playerNameSelect');
let options = players.map(player => `<option value=${player}>${player}</option>`).join('\n');
playerNameSelect.innerHTML = options;

//When player name select element changes:

//Sets playerName variable
playerNameSelect.addEventListener("change", (event) => {
  playerName = playerNameSelect.selectedOptions[0].textContent;
});

/*
Makes usedDrivers div visible
Sets h2 in usedDrivers div
Populates list of used drivers
*/
playerNameSelect.addEventListener("change", (event) => {
   document.getElementById('usedDrivers' ).style.display = 'block';
document.getElementById('playerHasUsed').innerHTML = `${playerName} has used:`;
 const playerIndex = choices.indexOf(playerName);
  const playerFirstChoice = playerIndex + 1;
  const playerLastChoice = playerIndex + racesCompleted + 1;
  const usedDriverList = choices.slice(playerFirstChoice, playerLastChoice);
  const listOfUsedDrivers = document.getElementById('listOfUsedDrivers');
  let options = usedDriverList.map(driver => `<li value=${driver} id=${driver}>${driver}</li>`).join('\n');
  listOfUsedDrivers.innerHTML = options;
});

/*
Makes avbailableDrivers div visible
Sets h2 in availableDrivers div
Works out list of used drivers again because I couldn't work out how to do it in global scope
Works out & populates list of available drivers
*/
playerNameSelect.addEventListener("change", (event) => {
  document.getElementById('availableDrivers').style.display = 'block';
  document.getElementById('playerHasAvailable').innerHTML = `${playerName} still has:`;
  const playerIndex = choices.indexOf(playerName);
  const playerFirstChoice = playerIndex + 1;
  const playerLastChoice = playerIndex + racesCompleted + 1;
  const usedDriverList = choices.slice(playerFirstChoice, playerLastChoice);
  const listOfAvailableDrivers = document.getElementById('listOfAvailableDrivers');
  let availableDrivers = driverList.filter(x => !usedDriverList.includes(x));
  let options = availableDrivers.map(driver => `<li value=${driver} id=${driver}>${driver}</li>`).join('\n');
  listOfAvailableDrivers.innerHTML = options;
});

And the HTML for it:

<div class="contentBox">
<h1>F1 Driver Reminder</h1>
<p class="lead">Select your name to see your options</p>
    </div>

<div class="contentBox">
  <h2>Who are you?</h2>
  <div class="flexAlign">
  <label for="playerName">
    <select id="playerNameSelect">  
    </select>
      </label>
      </div>
</div>


<div class="contentBox" id="usedDrivers">
  <h2 id=playerHasUsed>[Player name] has used:</h2>
  <ul id="listOfUsedDrivers">
  </ul>
</div>
  
<div class="contentBox" id="availableDrivers">
  <h2 id=playerHasAvailable>[Player name] still has:</h2>
  <ul id="listOfAvailableDrivers">
  </ul>
</div>