8

I have long list of data (for an example say States and their Abbreviations) I want to display in HTML table. Instead of displaying the data in 2 x 50 table I would like it more compact for larger screens (so the user does not have scroll up and down as much but still won't have to scroll horizontally)

So this would grow dynamically:

State       | Ab
-------------------
Alabama     | AL
Alaska      | AK
Arizona     | AZ
Arkansas    | AR
California  | CA
Colorado    | CO
Connecticut | CT

to:

State       | Ab | State       | Ab |
--------------------------------------
Alabama     | AL | California  | CA |
Alaska      | AK | Colorado    | CO |
Arizona     | AZ | Connecticut | CT |
Arkansas    | AR |

or this:

State       | Ab | State      | Ab | State       | Ab |
---------------------------------------------------------
Alabama     | AL | Arkansas   | AR | Colorado    | CO |
Alaska      | AK | California | CA | Connecticut | CT |
Arizona     | AZ |

etc....

Depending on the screen width.

I am doing this in Rail 3 app with jQuery so I prefer jQuery solution but open to any ideas.

1
  • Same type of question has been already answered on SO see In the answer given by nnnnnn user you need to add one more column :) Commented Jun 28, 2012 at 5:49

4 Answers 4

1

Here's a demo of a tableless solution. It is only currently set to arrange columns on page load and would take some minor additions for resize handling.

DEMO: http://jsfiddle.net/DPRsj/

It's based on a json array I had with array looking like:

   [{"state":"AK","name":"Alaska"}........]

The html could be sent to page without needing to parse json, minor difference in getting length of state list would be needed

HTML:

<div id="state_wrap">
    <div id="state_header"></div>
    <div id="state_list"></div>   
</div>

CSS:( very basic)

.state{  width:150px;  border:1px solid grey; border-top:none}
.st_name{ width: 120px;float:left}
.st_ab{ width:30px; margin-left: 120px;}
#state_header .state{
    font-weight:bold;
    color:blue;
    margin-right:10px;
    width: 150px;
    float:left;
}
.column{ width: 152px; float:left;margin-right:10px;}

JS:

$(function() {
    /* parse json to html*/
    var html = [];    
    $.each(states, function() {
        html.push(stateContainer(this.name, this.state));
    });    
    html.push('<div style="clear:both"></div>');    
    $('#state_list').html(html.join(''))
     /* END parse json to html*/

    var listW = 160, /* column width, including margin, set by css*/
        contW = $('#state_wrap').width();
    var num_cols = Math.floor(contW / listW)
    /* create headings*/
    var topHtml = [];
    for (i = 0; i < num_cols; i++) {
        topHtml.push(stateContainer('State', 'Abr'))
    }

    $('#state_header').html(topHtml.join(''));
    /*END create headings, START: create columns*/
    var start = 0,
        end = 0;
    var state_per_col = Math.floor(states.length / num_cols);
    var $states = $('#state_list .state')
    for (i = 0; i < num_cols; i++) {
        start = end;
        end = start + state_per_col + 1;
        $states.slice(start, end).wrapAll('<div class="column"></div>')
    }
});

function stateContainer(name, abr) {
    return '<div class="state"><div class="st_name">' + name + '</div><div class="st_ab">' + abr + '</div></div>';
}
1
  • Why would you not want to use a table to represent data?
    – Alex
    Commented Apr 4, 2013 at 6:23
1

Couldn't find an off-the-shelf solution, but this function should do the trick!

/*
This function will create a table with fixed `COL_WIDTH' (default=150 px) 
that uses as many columns as can be fit into the HTML element with id `table_id'.

A one-dimensional array of values to fill the table with should be passed in as 
`data'.
*/
function fillScreenWithData(table_id, data, COL_WIDTH){
    if (!COL_WIDTH) COL_WIDTH = 150;

    TABLE = $(table_id);
    alert(TABLE);
    TABLE_STRING = "<table>"
    var doc_width = TABLE.width();
    var num_cols = Math.floor(doc_width / COL_WIDTH);
    var num_rows = Math.ceil(data.length / num_cols); 

    for (var i = 0; i < num_rows; i++){
        TABLE_STRING += "<tr>";
        for (var j = 0; j < num_cols; j++){
            TABLE_STRING += "<td>";
            index = i + j*num_rows;
            if (index < data.length) {
                TABLE_STRING += data[index];
            }
            TABLE_STRING += "</td>"
        }
        TABLE_STRING += "</tr>"
    }
    TABLE_STRING += "</table>"
    TABLE.html(TABLE_STRING);
}

// probably fetch this JSON array of data with an AJAX request
var data = ["Alabama", 
        "Alaska",
        "Arkansas",
        "California",
        "Colorado",
        "Connecticut",
        "Extra Item",
        ]

// run the function on page load
$(function(){fillScreenWithData("#table", data)});
0

Depending on browser requirements and how important the column headers are for you css3 has a column-width css property you can set. (-webkit and -moz prefixes currently required.)

0

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

   
    <table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col">Handle</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Mark</td>
      <td>Otto</td>
      <td>@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jacob</td>
      <td>Thornton</td>
      <td>@fat</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td colspan="2">Larry the Bird</td>
      <td>@twitter</td>
    </tr>
  </tbody>
</table>
    
    
    
    

Use bootstrap for this.

Not the answer you're looking for? Browse other questions tagged or ask your own question.