0

I have an HTML table and I need the first column of the table to be fixed so I can scroll all the way the the right and see the information related to any record of the first column, when I try to scroll the first column is ok, but it also put as fixed the next two headers of my table.

This is my jquery:

(function($) {

$.fn.tableHeadFixer = function(param) {
    var defaults = {
        head: true,
        foot: false,
        left: 0,
        right: 0
    };

    var settings = $.extend({}, defaults, param);

    return this.each(function() {
        settings.table = this;
        settings.parent = $("<div></div>");
        setParent();

        if(settings.head == true)
            fixHead();

        if(settings.left > 0)
            fixLeft();

        // self.setCorner();

        $(settings.parent).trigger("scroll");

        $(window).resize(function() {
            $(settings.parent).trigger("scroll");
        });
    });

    function setTable(table) {

    }


    function setParent() {
        var container = $(settings.table).parent();
        var parent = $(settings.parent);
        var table = $(settings.table);

        table.before(parent);
        parent.append(table);
        parent
            .css({
                'width' : '100%',
                'height' : container.css("height"),
                'overflow' : 'scroll',
                'max-height' : container.css("max-height"),
                'min-height' : container.css("min-height"),
                'max-width' : container.css('max-width'),
                'min-width' : container.css('min-width')
            });

        parent.scroll(function() {
            var scrollWidth = parent[0].scrollWidth;
            var clientWidth = parent[0].clientWidth;
            var scrollHeight = parent[0].scrollHeight;
            var clientHeight = parent[0].clientHeight;
            var top = parent.scrollTop();
            var left = parent.scrollLeft();

            if(settings.head)
                this.find("thead tr > *").css("top", top);

            if(settings.left > 0)
                settings.leftColumns.css("left", left);

        }.bind(table));
    }

    function fixHead () {
        var thead = $(settings.table).find("thead");
        var tr = thead.find("tr");
        var cells = thead.find("tr > *");

        setBackground(cells);
        cells.css({
            'position' : 'relative'
        });
    }


    function fixLeft () {
        var table = $(settings.table);

        var fixColumn = settings.left;

        settings.leftColumns = $();

        for(var i = 1; i <= fixColumn; i++) {
            settings.leftColumns = settings.leftColumns
                .add(table.find("tr > *:nth-child(" + i + ")"));
        }

        var column = settings.leftColumns;

        column.each(function(k, cell) {
            var cell = $(cell);

            setBackground(cell);
            cell.css({
                'position' : 'relative'
            });
        });
    }


    function setBackground(elements) {
        elements.each(function(k, element) {
            var element = $(element);
            var parent = $(element).parent();

            var elementBackground = element.css("background-color");
            elementBackground = (elementBackground == "transparent" || elementBackground == "rgba(0, 0, 0, 0)") ? null : elementBackground;

            var parentBackground = parent.css("background-color");
            parentBackground = (parentBackground == "transparent" || parentBackground == "rgba(0, 0, 0, 0)") ? null : parentBackground;

            var background = parentBackground ? parentBackground : "white";
            background = elementBackground ? elementBackground : background;

            element.css("background-color", background);
        });
    }
};
})(jQuery);

And I also put the example in this Fiddle on it the window dont let the example to scroll so if you load it locally and make the window small you'll be able so scroll and see the issue I mentioned before with the headers of the table

Hope someone help me on this!

1 Answer 1

2

If you're interested, this is possible simply with just a HTML and CSS solution, no JS. Much easier to implement, and also works cross browser will no bugs like what your above JS may produce.

CSS:

section {
  position: relative;
  border: 1px solid #000;
  padding-top: 37px;
  background: #500;
}
section.positioned {
  position: absolute;
  top:100px;
  left:100px;
  width:800px;
  box-shadow: 0 0 15px #333;
}
.container {
  overflow-y: auto;
  height: 200px;
}
table {
  border-spacing: 0;
  width:100%;
}
td + td {
  border-left:1px solid #eee;
}
td, th {
  border-bottom:1px solid #eee;
  background: #ddd;
  color: #000;
  padding: 10px 25px;
}
th {
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}
th div{
  position: absolute;
  background: transparent;
  color: #fff;
  padding: 9px 25px;
  top: 0;
  margin-left: -25px;
  line-height: normal;
  border-left: 1px solid #800;
}
th:first-child div{
  border: none;
}

HTML:

<section class="">
  <div class="container">
    <table>
      <thead>
        <tr class="header">
          <th>
            Table attribute name
            <div>Table attribute name</div>
          </th>
          <th>
            Value
            <div>Value</div>
          </th>
          <th>
            Description
            <div>Description</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>align</td>
          <td>left, center, right</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
        </tr>
        <tr>
          <td>bgcolor</td>
          <td>rgb(x,x,x), #xxxxxx, colorname</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
        </tr>
        <tr>
          <td>border</td>
          <td>1,""</td>
          <td>Specifies whether the table cells should have borders or not</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>

WORKING EXAMPLE

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your time, I check your example, the headers are ok, but I also need the first column to be static, like you in an Excel file, that the first column is static and you scroll all over the other columns.
Why don't you use a JS plugin such as data tables? There is a great example here that allows for the fixing of headers and multiple columns. The plugin is also great for filtering data, searching, etc.
Thanks for your time, I saw that plug in but I really need to do it this way :(

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.