Home > Net >  I try to create a table dynamically but I can't do it
I try to create a table dynamically but I can't do it

Time:10-01

I'm trying to build a table dynamically in svelte but I'm stuck on the data display. I display well the th but for the td, the data are not in the right order.

Here are the data (the data are dynamic, the number of th and td can vary):

export default {
    columns: [
        {
            title: "ID",
            rows: [
                {
                    value: "1"
                },
                {
                    value: "2"
                },
                {
                    value: "3"
                }
            ]
        },
        {
            title: "Firstname",
            rows: [
                {
                    value: "Toto"
                },
                {
                    value: "John"
                },
                {
                    value: "Tata"
                }
            ]
        },
        {
            title: "Lastname",
            rows: [
                {
                    value: "Titi"
                },
                {
                    value: "Doe"
                },
                {
                    value: "Baba"
                }
            ]
        }
    ]
}

Here is the code snippet in svelte:

<script>
    import data from "./data";
    
    const formatTable = (columns) => {
        const rows = [];
        let newObject = {};
        for (let i = 0; i < columns.length; i  ) {
            for (let j = 0; j < columns[i].rows.length; j  ) {
                newObject = {
                    ...newObject,
                    [columns[i].title] : columns[i].rows[j].value
                }
            }
            rows.push(newObject);
        }
        return rows;
    }
    
    const htmlTable = formatTable(data.columns);
</script>


<h2>HTML Table</h2>

<table>
  <tr>
        {#each data.columns as column}
        <th>{column.title}</th>
        {/each}
  </tr>
    {#each Object.values(data.columns) as row, index}
    <tr>
      {#each row.rows as cell}
        <td>{cell.value}</td>
      {/each}
    </tr>
  {/each}
</table>

<style>
    table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
</style>

The current result: https://imgur.com/EBuliKz

You can see in the image that the IDs for example are not placed in the right order.

The goal is to loop on the columns and then on the rows by recovering the first element of each row then the second, ...

CodePudding user response:

That's possible but requires more complicated loop.

I propose to just restructure the data where it can be easily looped

columns = [{
    title: "ID",
    rows: [{
        value: "1"
      },
      {
        value: "2"
      },
      {
        value: "3"
      }
    ]
  },
  {
    title: "Firstname",
    rows: [{
        value: "Toto"
      },
      {
        value: "John"
      },
      {
        value: "Tata"
      }
    ]
  },
  {
    title: "Lastname",
    rows: [{
        value: "Titi"
      },
      {
        value: "Doe"
      },
      {
        value: "Baba"
      }
    ]
  }
]

// Will contain array of complete row
// i.e [[r1c1, r1c2, r1c3], [r2c1, r2c2, r2c3]]
const rows = []

columns.forEach((column, index) => {
  column.rows.forEach((row, rowIndex) => {
    if (!rows[rowIndex]) {
      rows[rowIndex] = [row.value]
    } else {
      rows[rowIndex].push(row.value)
    }
  })
})

console.log(rows)

Now just loop over that with ease

  • Related