Miumicream
Miumicream

Reputation: 89

How do you create dynamic rowspan tables in vuejs?

How do you render the following data into an html table with rowspans using vueJs?

Array

[
  {
    "id": 1,
    "name": "Dog",
    "param_id": 5,
    "total": "45.000"
  },
  {
    "id": 2,
    "name": "Cat",
    "param_id": 5,
    "total": "45.000"
  },
  {
    "id": 3,
    "name": "Fish",
    "param_id": null, 
    "total": "55.000"
  },
  {
    "id": 4,
    "name": "Bird",
    "param_id": 2, 
    "total": "75.000"
  }
]

This is an example of the result

tes

Upvotes: 0

Views: 1198

Answers (2)

Benson Okello
Benson Okello

Reputation: 394

@Foued I was able to work with your solution to produce something like this. enter image description here

However, I needed to highlight a few things someone may have to do if they would have more than one row to 'rowspan' on different columns.

  1. You don't need an else after the @if($loop->first)
  2. You'll have to use the @if($loop->first) for every row you will 'rowspan' under a different column. E.g Invoice Column, Country, Order Date etc.

From the screenshot, you can see that Invoice, Country, Deliver To, Supplier, Order Date,Store Branch, Paid and Payment Date columns have a merged row where else Item, Qty and Expiry Date columns have split rows.

Below is the code that produced that.

<table class="table table-bordered">
                <thead>
                  <tr>
                    <th>Invoice</th>
                    <th>Country</th>
                    <th>Deliver To</th>
                    <th>Supplier</th>
                    <th>Catalogue</th>
                    <th>Item</th>
                    <th>Qty</th>
                    <th>Expiry Date</th>
                    <th>Order Date</th>
                    <th>Store Branch</th>
                    <th>Paid</th>
                    <th>Payment Date</th>
                    </tr>
                    </thead>
                    <tbody>
                      @foreach ($data as $item)
                      @foreach ($item as $row)
                      <tr>
                        @if($loop->first)
                        <td rowspan="{{ count($item) }}">{{$row['invoice_number']}}</td>
                        <td rowspan="{{ count($item) }}">{{$row['country']}}</td>
                        <td rowspan="{{ count($item) }}">{{$row['deliver_to']}}</td>
                        <td rowspan="{{ count($item) }}">{{$row['supplier']}}</td>
                        @endif
                        
                        <td>{{$row['catalogue_number']}}</td>
                        <td>{{$row['commodity']}}</td>
                        <td>{{$row['quantity']}}</td>
                        <td>{{$row['expiry_date']}}</td>
                        
                        @if($loop->first)
                        <td rowspan="{{ count($item) }}">{{$row['order_date']}}</td>
                        <td rowspan="{{ count($item) }}">{{$row['branch_name']}}</td>
                        <td rowspan="{{ count($item) }}">{{$row['payment_status']}}</td>
                        <td rowspan="{{ count($item) }}">{{$row['payment_date']}}</td>
                        @endif
                        </tr>
                          @endforeach
                          @endforeach
                        </tbody>
                      </table>

I implemented the controller the same way @FouedMoussi did.

Upvotes: 0

Foued MOUSSI
Foued MOUSSI

Reputation: 4813

First you may use Laravel Collection groupBy method to groups the collection's items by a given key ('total')

Controller code

//...

$myElequentCollection = Model::where(...)->get();

$grouped = $myElequentCollection->groupBy('total');

$data = $grouped->toArray();

//outpout
/*
    [
        '45.000' => [
            ['id' => '1', 'name' => 'Dog', ...],
            ['id' => '2', 'name' => 'Cat', ...],
        ],
        '55.000' => [
            ['id' => '3', 'name' => 'Fish', ...],
        ],
        '75.000' => [
            ['id' => '4', 'name' => 'Bird', ...],
        ],
    ]
*/

//...

return view('viewName', compact('data'));

HTML code example

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Total</th>
    </tr>
  </thead>
  <tbody>
    @foreach($data as $item)
    @foreach($item as $row)
    <tr>
      <td> {{ $row['id'] }}</td>
      <td> {{ $row['name'] }}</td>
      @if($loop->first )
      <td rowspan="{{ count($item) }}">{{ $row['total'] }}</td>
      @else
      <td>{{ $row['total'] }}</td>
      @endif
    </tr>
    @enforeach
    @endforeach
  </tbody>
</table>

Upvotes: 2

Related Questions