Skip to content
Advertisement

How can I group sections within a table?

I am using Vue with Element UI to create a table. Currently I am trying to figure out a possible way to add a year/name to the popup and hit save to have it show up as one of those headers shown in the ss with ‘add trim’ next to it? Add trim button would add those rows to the table but only for that model year/name group.

To sum things up, I’m looking for a way to associate certain rows to the headers that say the models name/year.enter image description here

<template>
  <div class="home">
    <div class="table-container">
      <div class="top-buttons">
        <div @click="override = true">add new override</div>
        <h1>Assigned checklist items</h1>
        <div @click="vehicle = true">add vehicle model</div>
      </div>
      <input type="text" placeholder="filter" class="filter" />
      <el-table :data="tableData" height="600" style="width: 100%">
        <el-table-column prop="trim" label="TRIM" width="200"> </el-table-column>
        <el-table-column prop="technical" label="TECHNICAL" width="170"> </el-table-column>
        <el-table-column prop="customer_delivery" label="CUSTOMER DELIVERY" width="170"> </el-table-column>
        <el-table-column prop="customer_acceptance" label="CUSTOMER ACCEPTANCE" width="170"> </el-table-column>
        <el-table-column prop="off_the_truck" label="OFF THE TRUCK" width="170"> </el-table-column>
        <el-table-column prop="vim" label="VIM" width="170"> </el-table-column>
      </el-table>
    </div>

    <!-- Add Vehicle Model -->
    <el-drawer title="Add vehicle model" :visible.sync="vehicle" :direction="direction" :before-close="handleClose">
      <div class="vehicle">
        <span>
          <label for="year">MODEL YEAR</label>
          <input type="text" id="year" v-model="modelYear" placeholder="Model Year" />
        </span>
        <span>
          <label for="model">MODEL NAME</label>
          <input type="text" id="model" v-model="modelName" placeholder="Model NAME" />
        </span>
      </div>
      <div class="buttons">
        <el-button type="primary">Save</el-button>
        <button class="cancel" @click="vehicle = false">Cancel</button>
      </div>
    </el-drawer>

    <!-- Add New Override -->
    <el-drawer title="Add new override" :visible.sync="override" :direction="direction" :before-close="handleClose">
      <span>Hi, there!</span>
    </el-drawer>
  </div>
</template>

<script>
export default {
  name: 'Home',
  data() {
    return {
      modelYear: '',
      modelName: '',
      vehicle: false,
      override: false,
      direction: 'rtl',
      filter: '',
      tableData: [
        {},
        {},
        {
          trim: '2016-05-03',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-02',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-04',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-01',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-08',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-06',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-07',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
        {
          trim: '2016-05-07',
          technical: 'Tom',
          customer_delivery: '123',
          customer_acceptance: '123',
          off_the_truck: '123',
          vim: '123',
        },
      ],
    };
  },
  methods: {
    handleClose(done) {
      this.$confirm('Are you sure you want to close this?')
        .then(() => {
          done();
        })
        .catch(() => {});
    },
  },
};
</script>

Advertisement

Answer

You may want to add multiple tbody elements to your table, one for each model of vehicle. This lets you group the rows so your “Add Trim” script can target whichever group it’s part of.

This example is sloppy and uses .insertAdjacentHTML and some formatting hacks. In real life, I’d use a series of .createElement and .appendChild calls (or even better, <template> elements whose contents could be reused for each button click) — but hopefully this at least makes the idea clear.

(I pre-populated the input fields to make the demo easier to use.)

// Identifies some DOM elements
const
  yearInput = document.getElementById("year"),
  nameInput = document.getElementById("model"),
  saveBtn = document.getElementById("saveBtn"),
  table = document.getElementById("table");

// Adds click listeners
saveBtn.addEventListener("click", addModel);
table.addEventListener("click", addTrim); // Clicks will bubble up to table


// Defines click listeners

function addModel(){
// Adds a model-specific `tbody` element when "Save" is clicked

  if(!yearInput.value || !nameInput.value){ return; } // Requires both inputs

  // Creates the new markup
  const
    modelText = `${yearInput.value} ${nameInput.value}`,
    tbodyMarkup = `<tbody><tr><th><span class="model">${modelText}</span><button class="addTrim">Add trim</button></th><th></th><th></th></tr></tbody>`;

  // Clears the inputs
  yearInput.value = "";
  nameInput.value = "";

  // Inserts the tbody markup
  table.insertAdjacentHTML("beforeend", tbodyMarkup);
}


function addTrim(event){
  // Adds rows in the current `tbody` when "Add trim" is clicked

  const btn = event.target; // Remembers which element was clicked
  if(!btn.classList.contains("addTrim")){return;} // Ignores irrelevant clicks

  // Finds the ancestor `tbody`, and creates the new markup
  const
    tbody = btn.closest("tbody"),
    trimMarkup = `<tr><td>GLI (255)</td><td>xxx</td><td>xxx</td></tr><tr><td>R-LINE (222)</td><td>xxx</td><td>xxx</td></tr><tr><td>S (220)</td><td>xxx</td><td>xxx</td></tr>`;

  // Inserts the markup, and disables the button
  tbody.insertAdjacentHTML("beforeend", trimMarkup);
  btn.setAttribute("disabled", "");
}
input {width: 50px;}
button {margin-left: 15px;}
tbody>tr, td:first-child {text-align: left;}
th {border-top: 1px solid grey;}
th + th, td + td {border-left: 1px solid grey;}
<label>YEAR<input id="year" value="2010"/></label>
<label>NAME<input id="model" value="Corolla"/></label>
<button id="saveBtn">Save</button>
<hr/>
<table id="table">
  <thead>
    <tr><th>Trim</th><th>Technical </th><th>Delivery</th></tr>
  </thead>
  <tbody>
    <tr>
      <th><span class="yearAndModel">2019 Jetta </span><button class="addTrim" disabled>Add trim</button></th>
      <th></th>
      <th></th>
    </tr>
    <tr><td>GLI (255)</td><td>xxx</td><td> xxx</td></tr>
    <tr><td>R-LINE (222)</td><td>xxx</td><td> xxx</td></tr>
    <tr><td>S (220)</td><td>xxx</td><td> xxx</td></tr>
  </tbody>
</table>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement