table widget

by sperske

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<select class="form-control" onchange="updateTable(this.value)">
  <option>FPP</option>
  <option>EXP</option>
</select>
<table class="table">
  <thead>
    <tr>
      <th scope="col" class="inputWeight">Item Weight</th>
      <th scope="col" class="inputItem">Item</th>
      <th scope="col" class="inputCancel"></th>
    </tr>
  </thead>
  <tbody id="itemTable">

  </tbody>
  <tbody id="emptyRow" style="display: none;">
    <tr>
      <td>
        <input type="number" class="form-control" name="Weight">
      </td>
      <td>
        <select class="form-control Item" name="Item">
          <option></option>
        </select>
      </td>
      <td><span class='actionClose'>&times;</span></td>
    </tr>
  </tbody>
</table>

CSS

tbody span.actionClose {
  display: none;
}
tbody.multi-select span.actionClose {
  display: inline;
}
span.actionClose {
  font-size: 25px;
  cursor: pointer;
}

select[name=Item] {
  width: 100%;
}

th.inputWeight {
    width: 130px;
}
th.inputCancel {
  width: 50px;
}

JavaScript

const items = {
  FPP: ["AAA", "BBB", "CCC"],
  EXP: ["DDD", "EEE", "FFF"]
}
const table = $('#itemTable');
const state = {
  itemType: undefined,
  availableItems: []
}

function appendInputRow() {
  const template = $("#emptyRow").clone().children()[0];
  state.availableItems.forEach((item) => {
    $('[name=Item]', template).append("<option>" + item + "</option>")
  });
  return template;
}

function updateTable(itemType) {
  state.itemType = itemType;
  state.availableItems = items[itemType];
  table.toggleClass('multi-select', itemType === 'EXP');
  table.empty().append(appendInputRow())
}

table.on('click', 'span.actionClose', function(e) {
	const row = $(e.target).parents('tr');
  const rows = $('tr', row.parent());
  
  if(rows.length > 1) {
  	row.remove();
  }
});

table.on('change', 'select[name=Item]', function(e) {
  const input = $(e.target);
  if (state.itemType === 'EXP') {
    const emptyInputs = $('select[name=Item]', table).filter((i, e) => $(e).val() === '');
    if (emptyInputs.length === 0) {
      table.append(appendInputRow())
    }
  }
});

// Trigger initial state
updateTable("FPP");