Jeff McMorris
Jeff McMorris

Reputation: 81

how do you create a grouped rows table in svelte?

I am trying to group my table rows to look like this with svelte. The svelte template code below is not working.

enter image description here

svelte template pseudocode

            {#each cities as city}
                {#if city.name != currentCity}
                    {@const currentCity = city.name}
                    <tr><th colspan="5" scope="colgroup">{currentCity}</th></tr>
                {/if}
                <tr><td>{city.person} - ({city.jobTitle})</td></tr>
            {/each}

Upvotes: 1

Views: 336

Answers (2)

brunnerh
brunnerh

Reputation: 185117

Do not try to mutate state within the template, it is not supposed to. Set up data in a functional way or ahead of time.

I.e. run a reduce on cities to create groups and iterate over the groups or, if you want to do the grouping iteratively, do so in the script and store it in a separate variable.

Upvotes: 0

Stephane Vanraes
Stephane Vanraes

Reputation: 16451

The best way is to preprocess the data to split it along the groups, Something like this could do

const grouped = data.reduce((acc, cur) => {
  if (!acc[cur.city]) acc[cur.city] = []
    acc[cur.city].push(cur)
    return acc
}, {})

This will make an object with the cities as keys and an array of all the people in this city as the value for the key.

Then you can use Object.entries to loop over those keys and with an inner loop render all the people:

{#each Object.entries(grouped) as [city, people]}
  <tr>
    <td colspan="5" scope="colgroup">{city}</td>
  </tr>
  {#each people as person}
    <tr>
      <td>{person.name}</td>
      <td>{person.role}</td>
    </tr>
  {/each}
{/each}

One benefit of this is that it will still group the people correct even if they are not sorted by city (like if you with Edinburgh, London, Edinburgh)

Upvotes: 3

Related Questions