<select><option>
to <table><td>
The demo provided below demonstrates how to:
- get the data from a selected
<option>
- convert the data to arrays
- collect
<td>
into arrays
- distribute the data arrays to the
<td>
s
Also, the overall OP (i.e. Original Post) code provided has been changed to show how the use of for
loops and NodeLists/HTMLCollections can be more efficient than the repetitive use of single references.
The Anatomy of an <option>
If I understood correctly you want a list of par ratings for each hole in a golf course selected in a <select>
. You did not provide these numbers so I added a new course (at index 1 of the <option>s
.) In the demo there's only one <option>
that's modified you'll have to provide the data for the rest of them yourself:
<option value="72" data-par='4,5,4,3,4,3,4,5,4,4,4,3,5,4,5,3,4,4' data-yards='445,575,350,240,455,180,450,570,460,495,505,155,510,440,530,170,440,465'>Masters Championship</option>
Normally, this data is in a database and sent in the form of a JSON, but because of the static nature of the data (golf courses don't change that often) this is a feasible way of listing golf course stats.
Getting the Data from <option>
value
attribute is "72"
for all golf courses because it's the most common par rating for 18 holes (I don't know of any professional tournaments that play 3 or 9.) To get this value:
- Reference the element and suffix it with the
.value
property:
var selectElement = document.getElementById('ID of select');
var selectValue = selectElement.value;
data-*
attributes, such as data-par
and data-yards
, can have any arbitrary String value but it isn't as simple as value
to access:
- Collect all
<options>
of <select>
into a HTMLCollection by suffixing reference to <select>
with the .options
property:
var optionsList = selectElement.options;
Note: I added yards per hole because it's always included with par ratings.
Then reference the selected <option>
:
var optionData = optionList[selectElement.selectedIndex];
Next, use .dataset
method and suffix it with the suffix of data-par
and data-yards
(i.e. par
and yards
):
var dataPar = optionData.dataset.par;
var dataYards = optionData.dataset.yards;
Getting the text inside <option>
Text Content</option>
, is similar to the previous procedure:
- Continued from the previous example using
optionData
which references the selected <option>
:
var optionText = optionData.text;
Summary
At this point you have four strings of data:
selctValue = "72"
dataPar = "4,5,4,3,4,3,4,5,4,4,4,3,5,4,5,3,4,4"
dataYards = "445,575,350,240,455,180,450,570,460,495,505,155,510,440,530,170,440,465"
optionText = "Masters Championship"
Of the four strings of data, group 2. dataPar
and dataYards
need to be converted into arrays. To move group 1. selectValue
to a <td>
and group 3. optionText
to a <caption>
:
var coursePar = document.getElementById('ID of td');
var courseTitle = document.querySelector('caption');
coursePar.innerHTML = selextedValue;
;
courseTitle.textContent = optionText;
Note: In this case .textContent
and .innerHTML
properties are interchangeable, but it is important to know how they are different so refer to the Reference section for details.
Converting <option>
Data Into Arrays
There are two data strings that appear as a series of numbers, but they are not:
dataPar = "4,5,4,3,4,3,4,5,4,4,4,3,5,4,5,3,4,4"
dataYards = "445,575,350,240,455,180,450,570,460,495,505,155,510,440,530,170,440,465"
If used in this state, it would show up as the same literal text in each <td>
:
- INCORRECT RESULT
A string: "445,575,350,240"
<td>445,575,350,240</td>
If converted into an Array of Strings each number is considered separately:
- CORRECT RESULT
An array: ["445","575","350","240"]
<td>445</td><td>575</td><td>350</td><td>240</td>
In this case use the array method split()
to convert a String by targeting a delimiter (i.e. the commas: ,
):
- Each array will now be in this form:
array = ["1","2","3"]
var parArray = dataPar.split(',');
var yardsArray = dataYards.split(',');
Summary
At this point there are two Arrays:
Convert NodeLists of <td>s
to Array of <td>s
For each array of data a row (i.e. <tr>
) of cells (i.e. <td>
) need to be referenced in an array. Here's the procedure laid out in a few lines:
For the sake of expediency the second array is: ArrayOfYardsTD
.
Summary
At this point there are four arrays:
Set the Arrays of <option>s
Data to the Arrays of <td>
To manipulate arrays a for
loop is usually adequate. To manipulate arrays in a less verbose and more efficient way, array methods can be used instead. The array method .forEach()
will take an array and run a function on each array element:
- For the sake of expediency,
tdArray
is the same as arrayOfParTD
and arrayOfYardsTD
dataArray
is the same as parArray
and yardsArray
tdArray.forEach(function(td, index) {
td.textContent = dataArray[index];
});
Summary
The final result should be:
th,td{border:1px solid #000;text-align:center}
th{text-align:left}
<table>
<tr id="trOfPar"><th>Par: </th><td>4</td><td>5</td><td>4</td><td>3</td><td>4</td><td>3</td><td>4</td><td>5</td><td>4</td><td>4</td><td>4</td><td>3</td><td>5</td><td>4</td><td>5</td><td>3</td><td>4</td><td>4</td></tr>
<tr id='trOfYards'><th>Yards: </th><td>445</td><td>575</td><td>350</td><td>240</td><td>455</td><td>180</td><td>450</td><td>570</td><td>460</td><td>495</td><td>505</td><td>155</td><td>510</td><td>440</td><td>530</td><td>170</td><td>440</td><td>465</td></tr>
</table>
Reference
- Get/Set Values
- Get/Set Multiple Values
- Array Methods
- Used in Demo
- Array Methods in Demo
Demo
The code presented in the previous sections is not the same as the code in the demo but similar enough hopefully. Each line of JavaScript is commented.
function listPlayers() {
/*
Collect all <input>s and <td class="player">s
into the NodeLists inputs and outputs respectively.
*/
var inputs = document.querySelectorAll('input');
var outputs = document.querySelectorAll('.player');
/*
For each iteration of outputs set its text to the
corresponding index of inputs value.
*/
for (let i = 0; i < outputs.length; i++) {
outputs[i].textContent = inputs[i].value;
}
return false;
}
function courseSelect() {
// <select id='tournaments'>
var select = document.getElementById('tournaments');
// HTMLCollection of all <option>s in select#tornaments
var opts = select.options;
// <caption>
var title = document.querySelector('caption');
// The last two <td> on <table id='course'>
var pT = document.getElementById('pT');
var yT = document.getElementById('yT');
/*
Set the inside HTML of <td id='pT'> to a String:
...that comprises of the text: "Course Par: "...
...followed by the value of <select id='tournaments'>
*/
pT.innerHTML = "Course Par: " + select.value;
/*
Set the text of <caption> to the text of the selected
<option>THIS TEXT</option>
*/
title.textContent = opts[select.selectedIndex].text;
/*
Get the values of [data-par] and [data-yards] from the
selected <option>
*/
var dataPar = opts[select.selectedIndex].dataset.par;
var dataYards = opts[select.selectedIndex].dataset.yards;
/*
Convert each of the Strings from [data-par] and
[data-yards] into arrays of Strings.
*/
// Array of par ratings of each hole
var parArray = dataPar.split(',');
// Array of yardages of each hole
var yardsArray = dataYards.split(',');
/*
Collect the <td>s of <tr id='par'> and <tr id='yards'>
into separate NodeLists then convert each into an Array.
*/
var parCells = Array.from(document.querySelectorAll('#par td'));
var yardsCells = Array.from(document.querySelectorAll('#yards td'));
/*
Fill each cell of tr#par with a value from the array of
par ratings according to matching index.
*/
parCells.forEach(function(par, index) {
par.textContent = parArray[index];
});
/*
Fill each cell of tr#yards with a value from the array
of yardages according to matching index.
*/
yardsCells.forEach(function(yards, index) {
yards.textContent = yardsArray[index];
});
/*
Convert each String value of the array of yardages into
a real Number
*/
var yardage = yardsArray.map(function(yrd) {
return parseInt(yrd, 10);
});
/*
Get the sum of all of the Numbers in the new array.
Note: the function addArray() is located outside of this
function.
*/
var totalYards = yardage.reduce(addArray);
// Set the total yards in td#yT
yT.innerHTML = "Yardage: " + totalYards;
return false;
}
/*
Utility function used to add two numbers.
The return value is used as a parameter to a
Array.reduce() method that runs an array's values
accumulatively.
*/
function addArray(total, number) {
return total + number;
}
th,
td {
border: 1px solid #000
}
caption {
font-size: 1.2rem;
font-weight: 900
}
#course th {
text-align: left
}
#course td,
.c {
text-align: center
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form id='golf'>
<fieldset id='players'>
<legend>Players</legend>
<input type="text" name="name1" id="p1"><br>
<input type="text" name="name2" id="p2"><br>
<input type="text" name="name3" id="p3"><br>
<input type="text" name="name4" id="p4"><br>
<button id='btn1' type="button" onclick='listPlayers()'>Done</button>
</fieldset>
<fieldset id='games'>
<legend>Tournaments</legend>
<select id="tournaments" onchange="courseSelect()">
<option disabled selected value=""> -- select a course -- </option>
<option value="72" data-par='4,5,4,3,4,3,4,5,4,4,4,3,5,4,5,3,4,4' data-yards='445,575,350,240,455,180,450,570,460,495,505,155,510,440,530,170,440,465'>Masters Championship</option>
<option value="72" data-par='' data-yards=''>Bossame Tournament</option>
<option value="72" data-par='' data-yards=''>OSLO Open</option>
<option value="72" data-par='' data-yards=''>The Closed Tournament</option>
<option value="72" data-par='' data-yards=''>IWGA Championship</option>
<option value="72" data-par='' data-yards=''>The Lawnmower Classic</option>
<option value="72" data-par='' data-yards=''>My World Match Play</option>
<option value="72" data-par='' data-yards=''>The Seasonal Championship</option>
<option value="72" data-par='' data-yards=''>The ABC Mexican Open</option>
<option value="72" data-par='' data-yards=''>The Pomponians Championship</option>
<option value="72" data-par='' data-yards=''>Anthony Burke World Tour Championship</option>
<option value="72" data-par='' data-yards=''>Never Be Royals Tournament</option>
<option value="72" data-par='' data-yards=''>The Huggy McGurber Invitational presented by Glakeside Resorts</option>
<option value="72" data-par='' data-yards=''>Thee Grind</option>
<option value="72" data-par='' data-yards=''>Glakeside Classic</option>
<option value="72" data-par='' data-yards=''>Resorts World Bimini Challenge</option>
<option value="72" data-par='' data-yards=''>World Golf Classic</option>
</select>
<br>
<hr>
<table id="leaderboard" width="100%">
<caption></caption>
<thead>
<tr>
<th width='55%'>Golfer</th>
<th width='5%'>toPar</th>
<th width='5%'>Thru</th>
<th width='5%'>Today</th>
<th width='5%'>R1</th>
<th width='5%'>R2</th>
<th width='5%'>R3</th>
<th width='5%'>R4</th>
<th width='10%'>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class='player'></td>
<td class='c'></td>
<td class='c'>F</td>
<td class='c'></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class='player'></td>
<td class='c'></td>
<td class='c'>F</td>
<td class='c'></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class='player'></td>
<td class='c'></td>
<td class='c'>F</td>
<td class='c'></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class='player'></td>
<td class='c'></td>
<td class='c'>F</td>
<td class='c'></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table id='course'>
<tbody>
<tr id='holes'>
<th>Hole: </th>
<td> 1 </td>
<td> 2 </td>
<td> 3 </td>
<td> 4 </td>
<td> 5 </td>
<td> 6 </td>
<td> 7 </td>
<td> 8 </td>
<td> 9 </td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
</tr>
<tr id='par'>
<th>Par: </th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr id='yards'>
<th>Yards: </th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Totals: </th>
<td id='pT' colspan='9'></td>
<td id='yT' colspan='9'></td>
</tr>
</tfoot>
</table>
</fieldset>
</form>
</body>
</html>