15

Is it possible to group data (using rowspan as explained here) in a table rendered with angularjs. Data is hierarchical, with state having many counties and each counties has multiple zipcodes. I want a table with only column for state, county, zip etc (so give a rowspan for length of the collection). I am not sure ng-repeat-start and ng-repeat-end can be used to achieve this. Please see the starter template here

 <table>
    <thead>
      <tr>
        <th>State</th>
        <th>County</th>
        <th>Zip</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat='st in states'>
        <td>{{st.name}}</td>
        <td></td>
        <td></td>
      </tr>
    </tbody>
  </table>

data

 var oh_counties = [
    {name: "Franklin", zips: [111,222,333,444,555]},
    {name: "Adams", zips: [111,222,333,444]},
    {name: "Allen", zips: [111,222,333]}
    ],
    wi_counties = [
    {name: "Dane", zips: [111]},
    {name: "Adams", zips: [111,222,333,444]}
    ]

    $scope.states = [
      {name: "OH", counties: oh_counties},
      {name: "WI", counties: wi_counties},
      ];

Edit:

A handcrafted version of the desired output is here http://plnkr.co/edit/T7toND0odx6qr8mVC121?p=preview

2
  • You could show what you mean by writing some desired output. Commented Jan 14, 2014 at 1:55
  • @SimonPlus please see it here plnkr.co/edit/T7toND0odx6qr8mVC121?p=preview Commented Jan 14, 2014 at 3:46

4 Answers 4

22

This is a variant of Holly Cummins' answer. The repeat is moved into the tr with ng-repeat-start and ng-repeat-end to prevent the tbody from being repeated. Also uses a slightly different method to hide the first row.

<tbody>
    <tr ng-repeat-start='st in states'>
      <th rowspan="{{st.counties.length}}">{{st.name}}</th>
      <td>{{st.counties[0].name}}</td>
    </tr>
    <tr ng-repeat-end ng-repeat='county in st.counties' ng-hide="$first">
       <td>{{county.name}}</td>
    </tr>
</tbody>
Sign up to request clarification or add additional context in comments.

3 Comments

For correctness, I think this should say st.counties[0].name
Great answer. Helped me a ton! I'm late to the party, but, but I rather like ng-if="!$first" to suppress the first cell in the first "following" row, because it keeps the HTML cleaner by not even having the element on the DOM in the first place :)
Agreed, that will produce better html, I just like the look on the ng-hide as the code looks a little more readable because it looks so close to saying 'hide the first'
9

This variant of KayakDave's answer improves the structuring by pulling the first nested row out to share the <tr> of the header:

<tbody ng-repeat='st in states'>
    <tr>
      <th rowspan="{{st.counties.length}}">{{st.name}}</th>
      <td>{{county[0].name}}</td>
    </tr>
    <tr ng-repeat='county in st. counties' ng-show="$index > 0">
       <td>{{county.name}}</td>
    </tr>
</tbody>

Comments

4

Sure. Is something like this what you had in mind:

<tbody ng-repeat='st in states'>
    <td rowspan="{{st.counties.length+1}}">{{st.name}}</td>
    <tr ng-repeat='county in st.counties'>
       <td>{{county.name}}</td>
    </tr>
</tbody>

I kept this example simple, nested 2 deep. But in the fiddle, below, I've got it nested 3 deep (so it includes zip).

demo fiddle

2 Comments

thanks for the example. But, it is not structured properly. see it with css class applied. plnkr.co/edit/FqCHTodxoJSegw6CySaS?p=preview . The third column is nested within second. Also, I am not sure tr can be nested within td.
A table can be nested in a td- with a tr inside the table- which is why I approached it that way. To create the structure you've added to your question I'd write a custom directive.
0

This may be usefull

<table>
    <tbody ng-repeat='st in states'>
        <tr>
            <th >{{st.name}}</th>
            <td>
                <table>
                    <tr ng-repeat='county in st.counties'>
                        <td>{{county.name}}</td>
                        <td>
                            <table>
                                <tr ng-repeat='zip in county.zips'>
                                    <td>{{zip}}</td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>

    </tbody>
</table>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.