I have been stuck on this for a few days now and could use some expert advice!
So, as a personal/learning project I'm making a fun little 'character relationship tracker' for my friends' D&D games. With this, I have a DB table of dummy dungeon masters as well as the game(s) they are running for the purpose of testing code. I am trying to create a cascading dropdown list generated from a mix of PHP and encoded to JSON as part of the submit new character form. It works! Except, in the database containing the info for the options, some have only one game in the list for a DM while others have multiple games for the same DM. For those singles, the JS is listing out every single letter as a different choice instead of just the single full option. I have tried remaking the PHP twice to try resolving this and shuffled through a handful of JS attempts to no avail. These changes have either broken the code completely or resulted in no changes.
This fiddle is what it is doing with my best attempt
as for the actual code:
HTML
<div class="selectdiv">
<select name="chargm" id="charadm" onChange="chgm(this.value);" required>
<option value="" selected="true" disabled>Game Master</option>
<?php foreach ($gameMasters as $masterName) { echo "<option value='". $masterName . "'>" . $masterName . "</option>"; } ?>
</select>
</div>
<div class="selectdiv">
<select name="chargame" id="chargm" required>
<option value="" selected="true" disabled>Game Name</option>
</select>
</div>
here is the PHP (I know it's super messy and redundant but I couldn't get it to work any other way for some reason and it does its job?)
//database connection stuff
$sqls = "SELECT * FROM datgames;";
$stmts = mysqli_query($conn, $sqls);
$resultcheck = mysqli_num_rows($stmts);
$gameMasters = array(); //create empty array of game masters.
$gameData = array(); //set up game list data array
//check if db can be read before contiuning.
if($resultcheck > 0){
while($row = mysqli_fetch_assoc($stmts)){ //while there are rows, add to array
$gameMasters[] = $row["datgamDM"]; //fill the gameMasters array with all gm's
$gmdm = $row["datgamDM"]; //define gmdm as the game master of the row
//copy existing info in gameData to preserve data
$anotm = $gameData;
//clear game data to reset it to avoid repeats
unset($gameData);
//create the key => value pair
$tmpar[$gmdm] = $row["datgamName"];
//merge the temp arrays and apply them to the global array
$gameData = array_merge_recursive($anotm, $tmpar);
//clear the temporary arrays to avoid repeats
unset($anotm);
unset($tmpar);
}
}else{ exit(); } //if db can't be reached, break the code.
$gameMasters = array_unique($gameMasters);
//print_r($gameData); //making sure the array is right. this line is removed once this is working
and the exact JSON output from the PHP currently with this loop
{
"Reid":[
"Curse of Strahd",
"ufkck"],
"bob":[
"Curse of Strahd",
"fffs"]
,"jomama":"blaal",
"taco":"salff"
};
and the JS adapted from divy3993's answer here
var list = <?php echo json_encode($gameData); ?>;
function chgm(value) {
if (value.length == 0) document.getElementById("chargm").innerHTML = "<option></option>";
else {
var games = "";
for (categoryId in list[value]) {
games += "<option>" + list[value][categoryId] + "</option>";
}
document.getElementById("chargm").innerHTML = games;
}
}
The question in short: What am I doing wrong in either PHP (most likely the cause) or Javascript that is causing the words in single-object groups to split into letters instead of showing the full word as the only option for the second drop down option?
Or rather, how do I get the PHP to make single-entries to show up as a multidimensional array while keeping the key so it shows up as an array in the JSON object?