7

Hi I need to convert columns to rows and rows to columns. I have both column headers and rows headers to the left. The row headers are just bold text to the left of the row to define what the row is.

I am trying to make this table mobile friendly. The table is 7 columns wide and the 7 columns do not show in a smart phone. So my idea is to use a media query to display a table where the columns and rows are switched since there will be no more than 3 rows. Can this be done?

1
  • Could you jsfiddle your table ? How many rows it have? Commented May 9, 2014 at 4:04

3 Answers 3

20

DEMO

Css Solution: Simply turn your td & th to display:block; & your tr to display:table-cell;

CSS:

@media screen and (max-width:767px) {
    table tr > *{
        display: block;
    }
    table tr {
        display: table-cell;
    }
}

Drawback: If your cells have too much data the layout will break Example.

jQuery Solution: We can keep track of element height to stay the same DEMO

JS:

$(function () {
    switchRowsAndCols("table", 767);
});

function switchRowsAndCols(thisTable, resolution) {
    if ($(window).width() < resolution) {
        switchRowsAndColsInnerFun(thisTable);
    }
    $(window).resize(function () {
        if ($(window).width() < resolution) {
            switchRowsAndColsInnerFun(thisTable);
        }else{
            switchRowsAndColsRemove(thisTable);
        }
    });
};

function switchRowsAndColsRemove(thisTable) {
    $("tr > *", thisTable).css({
        height: 'auto'
    });
};

function switchRowsAndColsInnerFun(thisTable) {
    var maxRow = $("tr:first-child() > *", thisTable).length;

    for (var i = maxRow; i >= 0; i--) {

        $("tr > *:nth-child(" + i + ")", thisTable).css({
            height: 'auto'
        });

        var maxHeight = 0;

        $("tr > *:nth-child(" + i + ")", thisTable).each(function () {
            var h = $(this).height();
            maxHeight = h > maxHeight ? h : maxHeight;
        });

        $("tr > *:nth-child(" + i + ")", thisTable).each(function () {
            $(this).height(maxHeight);
        });
    };
};
Sign up to request clarification or add additional context in comments.

3 Comments

@NicholasHazel That simple solution had an issue -- if you put too much data i.e line break the layout crumbled & i cant think of any css solution so here is some jQuery -- please see my updated answer.
@ImranBughio - Decided to toss out a super quick strict jQuery solution. If you're going to use jQuery at all, use it well :-) (your answer was perfectly reasonable as well).
Also add table colgroup { display: none; }
2

Well, figured I'd offer a slightly different jQuery solution to your dilemma for other people looking for additional help.

If you have to use a script, might as well make it do everything (the following script takes 4.2ms to run, which seems pretty reasonable to me :-)

Essentially what the below is doing is taking your tabular-data and converting it to a multidimensional array.

1, 2, 3, 4
5, 6, 7, 8 
9, 10, 11, 12

Becomes:

[[1,5,9],[2,6,10],[3,7,11],[4,8,12]]

Then, it's just a matter of having it rewrite your table based on the new array with a couple for-loops.

One thing to note, you would have to bind this to a media query or window.resize handler to get the acquired affect you're looking for. That is as easy as changing the on.click handler I have assigned.

Take a look! It's pretty nifty:

http://jsfiddle.net/jsR7n/1/

HTML:

<input type="button" id="switch" value="switch" \>
<table id="switchItems">
<tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
</tr>
<tr>
    <td>...etc

jQuery Script:

$(function(){
    $('#switch').on('click', function(){
        var items = [];
        var itemsConv = [];
        var table = $('#switchItems');
        var row,cell;

// FIND ALL OF THE DATA
        $("tr").each(function(){
            var trRow = [];
            $(this).children().each(function() {
                trRow.push($(this).text());
            });
            items.push(trRow);
        });
        for(var j=0;j<items[0].length;j++){
            var newRow = [];
            for(var i=0;i<items.length;i++){
                newRow.push(items[i][j]);
            }
            itemsConv.push(newRow);
        }

// KILL OUR CURRENT DATA IN THE TABLE
        table.empty();

// REWRITE OUR TABLE WITH NEW DATA
        for(var i=0; i<itemsConv.length; i++){
            row = $( '<tr />' );
            table.append( row );
            for(var j=0; j<itemsConv[i].length; j++){
                cell = $('<td>'+itemsConv[i][j]+'</td>');
                row.append( cell );
            }
        }
    });
});

Hope this was helpful!

http://jsfiddle.net/jsR7n/1/

3 Comments

nice, i was just looking on internet there are lots of small script who do the same tasks but there isn't any proper registered jQuery plugin, may be we should upload a plugin our-self?
Sure, want to use git?
lets continue the discussion in Chat Room
0

Very simple way of doing it using html and css

table,
th,
td {
  border: 1px solid #000;
}

table {
  max-width: 100%;
}

@media screen and (max-width:767px) {
  table tr>* {
    display: block;
  }
  table tr {
    display: table-cell;
    vertical-align: top;
  }
}
<table>
  <tr>
    <th>Head 1</th>
    <th>Head 2</th>
    <th>Head 3</th>
    <th>Head 4</th>
    <th>Head 5</th>
    <th>Head 6</th>
    <th>Head 7</th>
  </tr>
  <tr>
    <td>Row 1 Cell 1</td>
    <td>Row 1 Cell 2</td>
    <td>Row 1 Cell 3</td>
    <td>Row 1 Cell 4</td>
    <td>Row 1 Cell 5</td>
    <td>Row 1 Cell 6</td>
    <td>Row 1 Cell 7</td>
  </tr>
</table>

https://jsfiddle.net/reishabh/b2d9wc3L/4/

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.