Home > Net >  Populating a table column-wise
Populating a table column-wise

Time:09-05

I am implementing a HTML table in my Rails application. Currently, I have in my view:

<table>
  <thead>
    <tr>
      <% @electives.each do |elective| %>
        <th><%= elective.name %></th>
      <% end %>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

Elective and Course are models in my application. I have created a has_and_belongs_to_many association between them, thereby creating a courses_electives table.

At present, my webpage looks like:

Screenshot of webpage

What I want to do next is display all the courses related to each elective under the elective name.

I think I can achieve this using:

<% @electives.each do |elective| %>
  <% elective.courses.each do |course| %>
    <%= course.name %>
  <% end %>
<% end %>

The problem I am facing with this approach is that it doesn't allow me to build my table vertically. I can create new <td> elements inside the above loops, but that will render data horizontally. That is, courses which belong to Software Engineering Elective A will end up being <td> entries in Software Engineering Elective B and so on.

What I want is:

Screenshot of image

How can I achieve this? Any help is very much appreciated. Thank you.

CodePudding user response:

You can use .transpose to flip the columns and the rows.

<% @electives.map(&:courses).transpose.each do |row| %>
  <tr>
    <% row.each do |course| %>
      <td>
        <%= course.name %>
      </td>
    <% end %>
  </tr>
<% end %>

Do be careful with nil-s here, because I assume your electives might not have exactly the same amount of courses.

CodePudding user response:

Sliim's suggestion is good. But what you're battling here is the limitations of html concepts that are over 30 years old. We now have grid and flexbox, which are much better ways to arrange elements on the page than tables. So how would this look in modern html? (well, I'll use haml b/c it's easier to see the structure, and b/c I'm lazy and haml rocks)

#electives
  - @electives.each do |elective|
    .elective
      .name= elective.name
      - elective.courses.each do |course|
        .course= course.name

This just gives you a bunch of divs, but with a little css magic we can create the arrangement that you want:

#electives {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.elective {
  display: flex;
  flex-direction: column;
}

The grid-template-columns 'auto-fit' declaration adjusts to however many columns you may have, whilst setting minimum and maximum widths. It's described here.

Of course, the flexbox doesn't care that there are different numbers of courses in each elective.

  • Related