Dragos
Dragos

Reputation: 2981

Table Column too high

I am using Datatables, a jQuery plugin for creating custom tables. I am trying to create now a table with many columns, at least one of them containing a lot of text. The problem is that the column with long text is not created wider, but taller, making the table more difficult for the user to read.

How can I make the text column wider and less higher?

Here is a screenshot with my problem:

enter image description here

Here is my problem visible:

http://live.datatables.net/ujudij/edit#javascript,html

Upvotes: 6

Views: 2928

Answers (12)

Bob Yang
Bob Yang

Reputation: 599

I've written a small jQuery plugin to limit text lines of an element, hope this can help.

/** 
* Binaray search with callback
*/
function bisearch(left, right, search, getter){
    var pos, result;
    if (typeof getter !== "function") {
        getter = function (x) {
            return x;
        };
    }

    while (left <= right) {
        pos = (left + right) / 2 | 0;
        result = getter(pos);

        if (result < search) {
            left = pos + 1;
        }
        else if (result > search) {
            right = pos - 1;
        }
        else {
            return pos;
        }
    }
    return -1;
}

;(function($){
    var getLineHeight = function(el) {
        var self = el,
            $self = $(self),
            content = $self.html(),
            lineHeight;

        if (typeof $self.attr("style") !== "undefined") {
            orgStyleAttr = $self.attr("style");             
        }

        $self.html("&nbsp;").css("min-height", "0px");
        lineHeight = $self.height();

        $self.html(content);

        if (typeof orgStyleAttr !== "undefined") {
            $self.attr("style", orgStyleAttr);
        } else {
            $self.removeAttr("style");
        }
        return lineHeight;
    }
    $.fn.limitLines = function(maxLines){
        $(this).each(function(){
            var self = this,
                $self = $(self),
                content = $self.html(),
                height = $self.height(),
                lineHeight = getLineHeight($self),
                maxHeight = lineHeight * maxLines;

            if (Math.floor(height/lineHeight) <= maxLines) 
                return;

            // this search will stop when the text meet the line count,
            // but the last line will be of any length
            var middleOfLastLine = bisearch(0, content.length, maxLines, function (n){
                $self.html(content.substring(0, n));
                return Math.floor($self.height() / lineHeight); 
            });

            // search for position from current to current plus one more line, 
            // until we find the excact position(p) to stop,
            // where if one more letter was added, 
            // there will be a new line 
            var endOfLastLine = bisearch(middleOfLastLine, content.length, maxLines + .5, function (n){
                $self.html(content.substring(0, n - 3) + '...');
                var before = Math.floor($self.height() / lineHeight);

                $self.html(content.substring(0, n - 2) + '...');
                var after = Math.floor($self.height() / lineHeight);

                return (before + after) / 2;
            });
            $self.html(content.substring(0, endOfLastLine -3) + '...');
        });
    };
})(jQuery);

Upvotes: 4

Amit Kriplani
Amit Kriplani

Reputation: 682

Improvising @Burhan's reply: you can limit the characters directly displayed in the cell and add that to the title of the cell so it will create a tooltip kind of effect (== qTip??)

$(document).ready(function() {
    $('#example').dataTable({
    "sScrollX":"100%",
    "fnInitComplete": function(oSettings, json) {

        $('#example tr').each(function(i){
           $('td', this).each(function(j){
               // get length of text
               var l = $(this).text().length;
               var limit = 200;
               // set larger width if text length is greater than 300 characters
               if(l > limit){
                   $(this).attr('title',$(this).text())
                          .text($(this).text().substr(0,limit));
               }
           });
        });
    }
  });
});

change limit variable to whatever is confortable to you.........

Upvotes: 0

Aamir Mahmood
Aamir Mahmood

Reputation: 2724

In my view you should limit the out put from your script on server side, It will create better visual effect, but also saves some bandwidth, and will reduce page load

Upvotes: 0

echo_Me
echo_Me

Reputation: 37233

your solution is the %

change the name of this td class from odd gradeA to what_ever and add this

    width: 80%;

of course you can play with it how much you want .

or change this

 <tr class="odd gradeA"> //of the long text

to

  <tr style="width: 80%">  

and all other tds will be triggered so you can also make the same thing to other tds how much u like by % hope it helps

Upvotes: 0

FrancescoMM
FrancescoMM

Reputation: 2960

You can enlarge a column as you wish, I used 70% but you can also use pixels like 400px

http://live.datatables.net/ajemid/4/edit

$(document).ready(function() {
  $('#example').dataTable({
    "sScrollX":"100%",
     "aoColumnDefs": [
      { "sWidth": "70%", "aTargets": [ 0 ] }
    ]
  });
} );

"aTargets": [ 0 ] is for the first column, 1 for the second, etc..

For limiting the text, you could apply css properties like max-height:200px; and overflow:hidden; you could also apply a vertical gradient (transparent to white) over the bottom of the cell to give a nice fading-to-white effect to the long cell.

Upvotes: 2

James Jithin
James Jithin

Reputation: 10555

Specify your own width for each column.

$(document).ready(function() {
  $('#example').dataTable({
    "sScrollX":"100%",
    "aoColumns": [
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" },
      { "sWidth": "30%" }
    ]
  });
} );

Upvotes: 1

technosaurus
technosaurus

Reputation: 7812

You can make it scrollbars automatically appear on oversized data

<style>
.box{width:250;height:75;overflow:auto}
</style>

<div class="box" >your data here will only have a scrollbar if it overflows your predefined height width parameters</div>

Upvotes: 1

user677526
user677526

Reputation:

The simplest thing to do is wrap anything that goes into the table with a nobr html tag. It may not be the most elegant solution, but it will work, and you can use CSS to limit your cell widths and set your overflows. I cloned your example here.

Reading through the DataTables documentation, the manual solution might only work if you're calling datatable() on an existing DOM element. If you want to do this while loading data from an array or from an AJAX source, you might have to programmatically wrap the data in each table cell with nobr tags using jQuery. The nice thing about this is that you can have more control over what you decide to nowrap.

The DataTables API provides pre-init or the post-init API calls - you can tie a callback to a jQuery function that iterates through all the TDs in the table and wraps the contents in nobr tags.

I hope this made sense. Best of luck!

Upvotes: 1

Matanya
Matanya

Reputation: 6346

you need to use aoColumnDefs which allows you to target specific columns by title or number, and set the width of the desired columns by using the plug-in's native sWidth property:

$(document).ready(function() {
   var data = $('#example').dataTable({
   "sScrollX":"100%",
   "aoColumnDefs": [
   { "sWidth": "1500px", "aTargets": [5] } // this will target the 6th column (the first being 0) 
]
});

});  

a working example

documentation

If you don't know in advance which columns to target you can always get the length of the string in each cell, and act accordingly. that is, if the length exceeds a certain no. of chars, you add the column number to an array, later passed to aTargets

Upvotes: 3

Burhan Uddin
Burhan Uddin

Reputation: 779

You can check the length of text for each td after datatable render is complete. If the text length exceeds you defined limit, you can then set a larger width for that table cell i.e td. This way you can widen any cell that exceeds your desired height even if you don't know where is it in the table

Here is the code

$(document).ready(function() {
    $('#example').dataTable({
    "sScrollX":"100%",
    "fnInitComplete": function(oSettings, json) {

        $('#example tr').each(function(i){
           $('td', this).each(function(j){
               // get length of text
               var l = $(this).text().length;
               // set larger width if text length is greater than 300 characters
               if(l > 300){
                   $(this).width(400);
               }
           });
        });
    }
  });
});

See this code demo here

You can also use cell height using var l = $(this).height(); but i don't think that will provide you correct result, because before adjusting width other cells in same row which may not have large texts also have same height, so their width property will also be changed using this, which is not correct for your situation, i guess

Although I think a better idea would be to trim the text to limit, add a "more" link and show full text using some plugin like qTip

Upvotes: 5

Roy Ling
Roy Ling

Reputation: 1632

Probably you may consider to use css text-overflow property: http://css-tricks.com/snippets/css/truncate-string-with-ellipsis/ and in conjunction with a tooltip of the cell which has a long text.

Upvotes: 6

Arun
Arun

Reputation: 68

$(document).ready( function () {
$('#example').dataTable( {
"bAutoWidth": false
} );
} );

Later set width for <td> inside your table.

Upvotes: 1

Related Questions