Robert Harvey
Robert Harvey

Reputation: 180868

How do I create a two-column snaking layout in ASP.NET MVC?

I have about a hundred short-text data items (this number can vary substantially) that I would like to put in a page and have the browser manage that into three columns within a surrounding div, arranged with the items going down and then across, like this:

A    F    L
B    G    M
C    H    N
D    I    O
E    K    ...

Is there a way to render this out as li's (or maybe just individual lines), and have the browser automatically collate it into three equal-height columns, possibly using CSS?

Are there any browser compatibility issues?

Upvotes: 4

Views: 6183

Answers (6)

eu-ge-ne
eu-ge-ne

Reputation: 28153

Without browser compatibility issues:

<% var rows = source.Count() % 3 == 0 ? source.Count / 3 : (source.Count / 3) + 1; %>
<table>
    <% for(int i=0; i<rows; i++) { %>
    <tr>
        <td><%= source.Skip(i).FirstOrDefault() %></td>
        <td><%= source.Skip(i+rows).FirstOrDefault() %></td>
        <td><%= source.Skip(i+rows*2).FirstOrDefault() %></td>
    </tr>
    <% } %>
</table>

We use the modulus operator to let us know if the division is even or not... if it is not, we're not going to add an extra row for the leftover columns. For more information, see http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx

For example look at https://stackoverflow.com/users HTML source - it uses <table>

Upvotes: 9

Robert Harvey
Robert Harvey

Reputation: 180868

After Xandy suggested Javascript, I did some googling for jQuery plugins, and found this:

Newspaper Columns JQuery Plugin
http://www.webmeisterei.com/petznick/2007/05/16/newspaper-columns-jquery-plugin/

Usage:
You need a Container with Elements like

<div id="npContainer">
  <div class="npItem">Item1</div>
  <div class="npItem">Item2</div>
</div>

...and you need the Columns

<div id="npColumn1"></div>
<div id="npColumn2"></div>
<div id="npColumn3"></div>

In Javascript just call:

jQuery().npColumns();

A web page that uses the plugin
http://www.bregenzerwald-news.at/?classifieds=1

Upvotes: 2

Keith
Keith

Reputation: 155792

You can't do this in CSS alone - though @griegs has shown how to do across then down.

If you always want 3 columns this should be easy with a little server side code and CSS - basically for each item you write something like:

<li>item</li>

Then at count/3 and count*2/3 add:

</ul><ul>

So you end up with something like:

<style>
    .three-column-panel > ul { 
        float:left; width:33%; list-style-type: none; text-indent:0; }
</style>    

<div class="three-column-panel">
    <ul>
        <li>a</li>
        <li>b</li>
        <li>c</li>
    </ul>
    <ul>
        <li>d</li>
        <li>e</li>
        <li>f</li>
    </ul>
    <ul>
        <li>g</li>
        <li>h</li>
    </ul>
</div>

Upvotes: 1

xandy
xandy

Reputation: 27421

html can be (actually doesnt really matters):

<div class="3col_vert">
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <div>d</div>
    ...
</div>

In javascripts (example in jquery in particular), you have to wrap them with cols, so that the resulting html (after manipulation of javascript) will become:

<div class="3col_vert">
    <div class="col_left">
        <div>a</div> ...
    </div>
    <div class="col_centre">
        <div>e</div> ...
    </div>
    <div class="col_right">
        <div>g</div> ...
    </div>
</div>

Jquery to mainpulate will be:

var vert_divs = $(".3col_vert div");
// Remove them from parent
$(".3col_vert").empty()
    .append("<div class='col_left'></div>") // append the wrapper cols to parent
    .append("<div class='col_center'></div>")
    .append("<div class='col_right'></div>");

// Now place them to the wrappers
var totalDivs = vert_divs.length; // count number of match divs

vert_divs.each(function(i) {
    if (i < totalDivs / 3)
        $(this).appendTo(".3col_vert div.col_left");
    else if (i<totalDivs * 2/3)
        $(this).appendTo(".3col_vert div.col_center");
    else
        $(this).appendTo(".3col_vert div.col_right");
});

The code above isn't too optimised ( I am sure lots of better algorithm can do), but the idea is there, you use javascript to manipulate the html into something like the above one, by putting the first 1/3 to left column, second 1/3 to center, and the rest to right. The last job is use CSS to make them into 3 columns, which I am not going to cover here but there's tons of tutorials out there, for instance, this one is one of those examples.

Upvotes: 1

griegs
griegs

Reputation: 22760

In the CSS world this is the only way I know to do three columns outside of a table of course.

<html>
    <div style="width:100px">
        <div style="float:left; width:33%;">a</div>
        <div style="float:left; width:33%;">bsdf</div>
        <div style="float:left; width:33%;">c</div>
        <div style="float:left; width:33%;">d</div>
        <div style="float:left; width:33%;">e</div>
        <div style="float:left; width:33%;">f</div>
        <div style="float:left; width:33%;">g</div>
    </div>
</html>

Clearly you wouldn't use all those style tags, instead you'd use an actual style. Notice the 33% as the width.

I tried this in IE and FirFox and no probs on either.

Upvotes: 2

griegs
griegs

Reputation: 22760

<div style="float: left">A</div>
<div style="float: left">B</div>
<div style="float: left">C</div>
<div style="float: left">D</div>
<div style="float: left">...</div>

Then place these into a div that has its width correctly set.

Upvotes: 1

Related Questions