1

I want to create a table such as the below with my data which is stored in Ruby Arrays:

______________________________________________________________
|    BUILD     |    PLATFORM    |       CATEGORY             |
|______________|________________|____________________________|
|              |                |      IP                    |
|              |   8k           |____________________________|
|              |                |      UMTS                  |
|              |________________|____________________________|
|   10.0.1.50  |                |      IP                    |
|              |                |____________________________|
|              |                |      UMTS                  |
|              |   9k           |____________________________|
|              |                |      Stability             |
|______________|________________|____________________________|
|              |                |      IP                    |
|   10.0.1.51  |   8k           |____________________________|
|              |                |      UMTS                  |
|______________|________________|____________________________|
|              |                |      IP                    |
|   11.0.1.50  |   9k           |____________________________|
|              |                |      UMTS                  |
|______________|________________|____________________________|

I have the following data in 3 of my arrays:

Arr1 
-------------------
row[0]    : row[1]
-------------------
11.0.1.50 :    2 
10.0.1.51 :    2 
10.0.1.50 :    5 


Arr2
---------------------------
row[0]    : row[1] : row[2]
---------------------------
11.0.1.50 : 9k     : 2 
10.0.1.50 : 9k     : 3 
10.0.1.51 : 8k     : 2 
10.0.1.50 : 8k     : 2 

Arr3
-------------------------------
row[0]    : row[1]  : row[2]
-------------------------------
10.0.1.50 : 8k      : IP 
10.0.1.50 : 8k      : UMTS 
10.0.1.51 : 8k      : IP 
10.0.1.51 : 8k      : UMTS 
10.0.1.50 : 9k      : IP 
10.0.1.50 : 9k      : Stability 
10.0.1.50 : 9k      : UMTS 
11.0.1.50 : 9k      : IP 
11.0.1.50 : 9k      : UMTS 

All those numbers in the arrays basically give me a count of the rowspan I might need for that particular entry.

I wrote some code in my rails view, but it does not seem to give me the desired output:

<% @l1_reg.each_with_index do |row1, index1| %> 
            <table>
                <tr>

                <!-- Build -->
                <td rowspan='<%= row1[1] %>'><strong><%= row1[0] %></strong></td>


                    <% @l2_reg.each_with_index do |row2, index2| %> 
                    <% if ((row2[0].to_s == row1[0].to_s) %>

                    <!-- Platform -->
                    <td rowspan='<%= row2[1] %>'><strong><%= row2[0] %></strong</td>


                        <% @l3_reg.each_with_index do |row3, index3| %> 
                        <% if ((row3[0].to_s == row2[0].to_s) && (row3[1].to_s == row2[1].to_s)) %>

                            <!-- Category -->
                            <td><%= row3[2] %></td>


                        <% end %>
                        <% end %>


                    <% end %>
                    <% end %>

                </tr>
             </table>  
        <% end %>
6
  • Have you thought about using divs instead of tables? You should only really use tables if what your displaying would be something you would put into a simple excel or csv spreadsheet. Basically if someone might use the data in a spreadsheet use a table, that way they can copy paste real easily. Otherwise, Even if the data may look like a 'table', just use divs, namely because what would normally be pretty simple views, get annoying and complicated way to fast. Commented Apr 26, 2013 at 22:19
  • @rovermicrover : I am using table for a lot of other reasons....i have a lot of javascripts in the background which work with the table too...I agree using divs would have been simpler....but that is not an option for me here. Commented Apr 26, 2013 at 22:23
  • what's the problem of your current code? Commented Apr 26, 2013 at 22:27
  • @IsmaelAbreu : It does not create the appropriate number of rows....and the data looks quite out of place. Commented Apr 26, 2013 at 22:37
  • 2
    @ rovermicrover An HTML table is totally fine for the example given. It's tabular data. Commented Apr 26, 2013 at 22:40

2 Answers 2

1

I have a solution, even though I think it's not the most beautiful view code (probably because its a table).

Define the three arrays in the controller (notice the sort for each array). You might already have the arrays. However, I list them here as a reference:

@l1_reg = [['11.0.1.50', 2],
           ['10.0.1.51', 2],
           ['10.0.1.50', 5]].sort
@l2_reg = [['11.0.1.50', '9k', 2],
           ['10.0.1.50', '9k', 3],
           ['10.0.1.51', '8k', 2], 
           ['10.0.1.50', '8k', 2]].sort
@l3_reg = [['10.0.1.50', '8k',        'IP'],
           ['10.0.1.50', '8k',      'UMTS'],
           ['10.0.1.51', '8k',        'IP'],
           ['10.0.1.51', '8k',      'UMTS'],
           ['10.0.1.50', '9k',        'IP'],
           ['10.0.1.50', '9k', 'Stability'],
           ['10.0.1.50', '9k',      'UMTS'],
           ['11.0.1.50', '9k',        'IP'],
           ['11.0.1.50', '9k',      'UMTS']].sort

Then you can do the following in your view:

<table>
  <thead>
    <tr>
      <td>Build</td>
      <td>Platform</td>
      <td>Category</td>
    </tr>
  </thead>
  <tbody>
    <% @l1_reg.each do | build, l1_row_sum| %>
      <% # platforms for current build
          @l2_reg.select {|b| build == b[0]}.each_with_index do | l2, l2_index | %>
        <% _, platform, l2_row_sum = l2 %>
        <% # category for current build, plaform
            @l3_reg.select {|b| build == b[0] and platform == b[1] }.each_with_index do | l3, l3_index | %>
          <% category = l3.last %>
          <tr>
            <% if l2_index == 0 and l3_index == 0 %>
              <td rowspan="<%= l1_row_sum %>"><%= build %></td>
            <% end %>
            <% if l3_index == 0 %>
            <td rowspan="<%= l2_row_sum %>"><%= platform %></td>
            <% end %>
            <td><%= category %></td>
          </tr>
        <% end %>
      <% end %>
    <% end %>
  </tbody>
</table>
Sign up to request clarification or add additional context in comments.

Comments

1

If you sort the arrays like in @tessi answer, you can write the view code more elegantly:

<% last_a = last_b = nil %>
<table>
  <% @l3_reg.each do |a, b, c| %>
    <tr>
      <% if a != last_a %>
        <% last_a, n = @l1_reg.shift %>
        <td rowspan="<%= n %>"><%= last_a %></td>
      <% end %>

      <% if b != last_b %>
        <% _, last_b, n = @l2_reg.shift %>
        <td rowspan="<%= n %>"><%= last_b %></td>
      <% end %>

      <td><%= c %></td>
    </tr>
  <% end %>
</table>

We loop the 3rd array because it's the number of rows.

For first column (a), we look at the last value we put there (for the first row, it's nil)

If the current is different from the last time, we take out the top row from the first array (which contains the column a values and their row span) and put the values there.

(shift is removing the first element from an array- like reverse pop)

We do the same for the second column (b)

We always put the value of column (c), as it is on every row.

As a bonus point, you can easily make this version independent on any number of columns :)

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.