1

I have a jsfiddle for this here: http://jsfiddle.net/biggest/3hjNc/58/

I've built a fairly decently working scrolling table. But if I have two or more of these kinds of tables, the jQuery functions I've built only seem to apply to the first one. How do I get it loop through each one, without adding any kind of "id" to each of the tables. I've tried various combinations of "each" and "find," which I'm fairly sure it will involve, as well as some kind of $(this), but I'm pretty sure I'm messing up the syntax somewhere along the line. Every attempt I try either fails outright, or only applies to the first table.

This may be obvious, but for the sake of clarity - since it's a scrolling table, it actually consists of several tables combined to appear as one. .tablesContainer = a div that wraps everything and should probably be the $(this) target, is my guess. The rest of the table structure should be seen in the jsfiddle above.

This is all of my jquery that puts everything into functions and then calls them at the bottom. The headerResize() function gets called at the end of whenever the tableSize() function runs.

$(document).ready(function(){
/****Table Functionality****/
    /*** Gives Header Cells equal width to Body Cells ***/
    /*--------------------------------------------------*/
    var $tableBodyScrollCell = $('.tableScroller tbody tr:first td');
    var $headerA = $('.headerScroller a');
    function headerResize(){
        $tableBodyScrollCell.each(function(index){
            $headerA.eq(index).width($(this).width());
        });
    }
    /*--------------------------------------------------*/
    /*** Changes height to equal viewerPort on big tables ***/
    var viewportHeight = window.innerHeight ? window.innerHeight : $(window).height();
    var $tablesContainerWidth = $('.tablesContainer').width();
    var $tableScroll = $('.tableScroller');
    var $headerHeight = $('.headerScroller').height();
    var $tableScrollTHeight = $('.tableScroller .table').height();
    var $tableScrollTWidth = $('.tableScroller .table').width();
    var $actionScroll = $('.actionScroller');
    var $topSectionHeight = $('#topSection').height();
    var $actnScrollDefaultW = Number(100);
    function tableSize(){  //17px difference to compensate for scrollbar
        if ($tableScrollTHeight > (viewportHeight-$topSectionHeight) - $headerHeight){
            if ($tableScrollTWidth == $tablesContainerWidth){
                $tableScroll.height((viewportHeight-$topSectionHeight) - $headerHeight) - 17;
            }
            else{
                $tableScroll.height((viewportHeight-$topSectionHeight) - $headerHeight);
            }
            $actionScroll.height((viewportHeight-$topSectionHeight) - $headerHeight - 17);
            $actionScroll.width($actnScrollDefaultW);
        }
        else{
            if ($tableScrollTWidth == $tablesContainerWidth){
                //alert("tableScrollTWidth = 100%");
                $tableScroll.height($tableScrollTHeight);
            }
            else{
                $tableScroll.height($tableScrollTHeight + 17);
            }
            $actionScroll.height($tableScrollTHeight);
            $actionScroll.width($actnScrollDefaultW + 17);
        }
        if ($tableScrollTHeight > $tableScroll.height() && $tableScrollTWidth == $tablesContainerWidth){//If there is a vertical scroll but NO Horizontal scroll
            $actionScroll.height($tableScroll.height());
        }
        $('.actionHead').width($('.actionScroller').width());
        headerResize();
    }
    /*--------------------------------------------------*/
    /*** Scrolls the table Header and Fixed column ***/
    $tableScroll.scroll(function(){         
        scrollHandler('tableScroller');
    });
    function scrollHandler(scrollContainer) {
        $('.headerScroller')[0].scrollLeft = $('.tableScroller')[0].scrollLeft;
        $('.actionScroller')[0].scrollTop = $('.tableScroller')[0].scrollTop;
    }
    /*--------------------------------------------------*/
    /*** runs functions ***/
    if ($(".tablesContainer").length == 0) {
        //Do nothing!!!
    }
    else{
        tableSize();
        $(window).resize(tableSize)
    }
});

Any help would be appreciated.

2
  • duplicate id in <div id="testTable" class="tablesContainer"> is not allowed Commented Apr 2, 2013 at 16:15
  • Thank you for pointing that out, but that was just an oversight in the example code I posted, as I just duplicated the same table. None of my script was calling on the ids, so it's not an issue with my local files. But good looking out. Commented Apr 2, 2013 at 16:20

2 Answers 2

1

I think I have you sorted.

Your selector on line 8 of your fiddle should read:

    var $tableBodyScrollCell = $('.tableScroller tbody tr:first-child td');

Relevant jQuery documentation can be found here http://api.jquery.com/first-child-selector/. The key takeaway is that :first limits you to one tr, whereas :first-child gives you one for each parent.

In your scrollHandler function on lines 59-62, you need to loop through your .headerScroller elements, for example:

function scrollHandler(scrollContainer) {
    $('.headerScroller').each(function(i) {
      $('.headerScroller')[i].scrollLeft = $('.tableScroller')[i].scrollLeft;
      $('.actionScroller')[i].scrollTop = $('.tableScroller')[i].scrollTop;
    });
 }
Sign up to request clarification or add additional context in comments.

5 Comments

Genius! You are a life saver. Works great. I had the rough idea but apparently I was applying that type of function to all of the wrong things. Good call on the "first-child" thing too. Much obliged.
jsfiddle.net/biggest/3hjNc/66 - If you could, there's now another problem involving the 2 tables, now that that is fixed. If the top one has more rows in it, the height for the 2nd is adjusting to match it. Any ideas for this?
The general problem is the way your tableSize() function is set up: you're setting the same size for all of your tables rather than looping through and setting a different size for each one.
That's about as much as I was able to deduce myself. Unfortunately, I have a big hang up on how/when to use $(this). I never seem to get it right and I'm fairly certain that's what I need to use (which probably means I'm wrong). When scripting, I understand the logic, I just struggle with syntax, and it's killing me.
Nevermind. I actually managed to figure it out. Thanks for the help though.
1

I haven't solved everything(yet!) but have found some improvement:

function scrollHandler(scrollContainer) {
    $('.headerScroller')[0].scrollLeft = $('.tableScroller')[0].scrollLeft;
    $('.actionScroller')[0].scrollTop = $('.tableScroller')[0].scrollTop;
    $('.headerScroller')[1].scrollLeft = $('.tableScroller')[1].scrollLeft;
    $('.actionScroller')[1].scrollTop = $('.tableScroller')[1].scrollTop;
}

you were only using index 0 before, so you were only altering the 1st table, now the second table header scrolls.

I think the other problem is here:

var $tableBodyScrollCell = $('.tableScroller tbody tr:first td');

the :first is making it select only the 1st table, I think.

1 Comment

Is there a way to make it loop through the multiple .tablesContainer? Because there are going to be instances of more than 2 and I have no way of knowing how many tables will be on each particular page at a time. Your way here seems to work, but only if you know how many tables there will be.

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.