简体   繁体   中英

Making table with resizable columns and selectable rows with jQuery UI

NOTE: My original question was whether I should use <div> s or <table> s for this task. I have found an answer myself: <div> s are more than twice as slower on Firefox and Chrome if you have ~2000 rows. So you must use <table> s for this. I decided to reedit my question to show how to do it (table with resizable columns and selectable rows using jQuery UI). Hope that it would be useful for anyone.

I'm making a web application (mainly for data entry & intranet usage). Need to render some data from SQL table in a standart way (rows as rows, columns as columns), but have some requirements:

  1. Data are received as JSON array with rigid format and need to be inserted from JavaScript.
  2. Columns must be resizable.
  3. Rows must be selectable.
  4. Body must be scrollable, header must stay above.

There are many ready-made JavaScript components for parts of this functionality, but the most complete are bloated, costs much and have bugs.

As I already have to use jQuery-ui for modal dialogs and tabs, I decided to try resizable and selectable effects. I managed to made them work for a standart HTML table using some tricks. Here is the code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head>
<script type='text/javascript' src='../Scripts/jQuery.js'></script>
<script type='text/javascript' src='../Scripts/jQuery-ui.js'></script>
<link href="../Css/ui-lightness/jquery-ui.css" type="text/css" rel="stylesheet" />
<style type='text/css'>
    .selectable .ui-selecting { background: #FECA40; }
    .selectable .ui-selected { background: #F39814; color: white; }
    .NCList table { table-layout:fixed; }
    .nc-cell { overflow: hidden; white-space:nowrap; }
    .NCList .ui-resizable-e { background: gray; }
    .NCList .y-scroll { overflow-y:auto; overflow-x:hidden; }
</style>

<script type="text/javascript">
    $(function() {
        var element = $('#MyParentDiv');
        $(".selectable", element).selectable({filter: 'tr'});
        $(".th0", element).resizable({
            alsoResize: '#MyParentDiv .header-container',
            stop: function(event, ui) {
                var width1 = $(".th0", element).width();
                $('.col0', element).width(width1);
                width1 = $(".header-container", element).width();
                $('.y-scroll', element).width(width1);
            },          
            handles: 'e'});
        $(".th1", element).resizable({
            alsoResize: '#MyParentDiv .header-container',
            stop: function(event, ui) {
                var width1 = $(".th1", element).width();
                $('.col1', element).width(width1);
                width1 = $(".header-container", element).width();
                $('.y-scroll', element).width(width1);
            },          
            handles: 'e'});
    });
    </script>

</head>
<body>
    <div id="MyParentDiv" class="NCList">
        <div class="header-container" style="width:215px;">
            <table><thead><tr> 
                <th><div class="nc-cell th0" style="width:100px;"> 
                    Short name
                </div></th>
                <th><div class="nc-cell th1" style="width:100px;"> 
                    Name
                </div></th> 
            </tr></thead></table>
        </div>
        <div class="y-scroll" style="max-height:100px;width:215px;">
            <table class="valuefield"> 
                <tbody class="selectable"> 
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                    <tr><td><div class="nc-cell col0" style="width: 100px">Some test values</div></td>
                        <td><div class="nc-cell col1" style="width: 100px">Some test values</div></td>
                    </tr>
                </tbody> 
            </table>
        </div>
    </div>
</body>
<html>

Purely from a semantic point of view, you should use tables where data needs to be presented. DIV is more for presentation and structuring your page design.

DIVs are more than twice as slow as TABLEs if you use jQuery.appendTo method to add 2000 rows on all major browsers. So I decided to use TABLEs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM