How to dynamically define the selected option on the select tag. (Using template literals)

310 Views Asked by At

I am trying to create some html elements with template literals. I know I could have a for loop and create the options one by one but I find that to be messy code. This is the best way that I could get working. Is there an easier way that I am completely missing?

/* creating the table */
  let propertyTable = document.createElement('table');
  propertyTable.classList.add('expand','ignore');


  let selected = ["", "", "", "", "", ""];

  switch (this.type) {
    case "number":
      selected[0] = "selected";
    break;
    case "dropDown":
      selected[1] = "selected";
    break;
    case "autoSet":
      selected[2] = "selected";
    break;
    case "plotly":
      selected[3] = "selected";
    break;
    case "gradeGroup":
      selected[4] = "selected";
    break;
    case "generate":
      selected[5] = "selected";
    break;
  }

  /* starting the property table */
  propertyTable.innerHTML = `<tr class="ignore">
    <th class="ignore">ID</th>
    <td class="ignore"><input class="tile ignore" value="${this.id}"></td>
  </tr>
  <tr class="ignore">
    <th class="ignore">Type</th>
    <td class="ignore">
      <select class="tile ignore">
        <option value="number" ${selected[0]} class="ignore">number</option>
        <option value="dropDown" ${selected[1]} class="ignore">dropDown</option>
        <option value="autoSet" ${selected[2]} class="ignore">autoSet</option>
        <option value="plotly" ${selected[3]} class="ignore">plotly</option>
        <option value="gradeGroup" c${selected[4]} lass="ignore">gradeGroup</option>
        <option value="generate" ${selected[5]} class="ignore">generate</option>
      </select>
    </td>
  </tr>`;
2

There are 2 best solutions below

1
Barmar On

Instead of the big switch statement, use an array of type names.

let selected = ["", "", "", "", "", ""];
let types = ["number", "dropDown", "autoSet", "plotly", "gradeGroup", "generate"];
let index = types.indexOf(this.type);
if (index >= 0) {
  selected[index] = "selected";
}

0
Taryn East On

Could you try a simpler function that you call with the relevant type, something like: (Note this is pseudocode, adjust as necessary)

function select_class(selector) do
  if (this.type == selector) do
    "selected"
  else
    ""
  end
end

Then when you're creating the select options, call it:

/* creating the table */
  let propertyTable = document.createElement('table');
  propertyTable.classList.add('expand','ignore');

  /* starting the property table */
  propertyTable.innerHTML = `<tr class="ignore">
    <th class="ignore">ID</th>
    <td class="ignore"><input class="tile ignore" value="${this.id}"></td>
  </tr>
  <tr class="ignore">
    <th class="ignore">Type</th>
    <td class="ignore">
      <select class="tile ignore">
        <option value="number" ${select_class("number")} class="ignore">number</option>
        <option value="dropDown" ${select_class("dropDown")} class="ignore">dropDown</option>
        <option value="autoSet" ${select_class("autoSet")} class="ignore">autoSet</option>
        <option value="plotly" ${select_class("plotly")} class="ignore">plotly</option>
        <option value="gradeGroup" ${select_class("gradeGroup")} lass="ignore">gradeGroup</option>
        <option value="generate" ${select_class("generate")} class="ignore">generate</option>
      </select>
    </td>
  </tr>`;

But really, having a function to build each option would be ideal. Something like:

function create_option(selector) do
  `<option value="${selector}" ${select_class(selector)} class="ignore">${selector}</option>`
end

Which you'd use something like:

  /* starting the property table */
  propertyTable.innerHTML = `<tr class="ignore">
    <th class="ignore">ID</th>
    <td class="ignore"><input class="tile ignore" value="${this.id}"></td>
  </tr>
  <tr class="ignore">
    <th class="ignore">Type</th>
    <td class="ignore">
      <select class="tile ignore">
        ${create_option("number"}
        ${create_option("dropDown"}
        ${create_option("autoSet"}
        ${create_option("plotly"}
        ${create_option("gradeGroup"}
        ${create_option("generate"}
      </select>
    </td>
  </tr>`;