これは、テーブルにスティッキーヘッダーを付けるのが本当に難しいことです。私は同じ要件を持っていましたが、asp:GridViewを使用していて、グリッドビューにスティッキーヘッダーがあると本当に思っていました。利用可能なソリューションはたくさんあり、すべてのソリューションを試すのに3日かかりましたが、どれも満足できませんでした。
これらのソリューションのほとんどで直面した主な問題は、配置の問題でした。ヘッダーをフローティングにしようとすると、ヘッダーセルとボディセルの配置がずれてしまいます。
いくつかのソリューションでは、ヘッダーを本文の最初の数行にオーバーラップさせる問題もありました。これにより、本文の行がフローティングヘッダーの後ろに隠れてしまいます。
これを達成するために自分のロジックを実装する必要がありましたが、これも完璧な解決策とは見なしていませんが、これは誰かにとっても役立つ可能性があります。
以下はサンプルテーブルです。
<div class="table-holder">
<table id="MyTable" cellpadding="4" cellspacing="0" border="1px" class="customerTable">
<thead>
<tr><th>ID</th><th>First Name</th><th>Last Name</th><th>DOB</th><th>Place</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Customer1</td><td>LastName</td><td>1-1-1</td><td>SUN</td></tr>
<tr><td>2</td><td>Customer2</td><td>LastName</td><td>2-2-2</td><td>Earth</td></tr>
<tr><td>3</td><td>Customer3</td><td>LastName</td><td>3-3-3</td><td>Mars</td></tr>
<tr><td>4</td><td>Customer4</td><td>LastName</td><td>4-4-4</td><td>Venus</td></tr>
<tr><td>5</td><td>Customer5</td><td>LastName</td><td>5-5-5</td><td>Saturn</td></tr>
<tr><td>6</td><td>Customer6</td><td>LastName</td><td>6-6-6</td><td>Jupitor</td></tr>
<tr><td>7</td><td>Customer7</td><td>LastName</td><td>7-7-7</td><td>Mercury</td></tr>
<tr><td>8</td><td>Customer8</td><td>LastName</td><td>8-8-8</td><td>Moon</td></tr>
<tr><td>9</td><td>Customer9</td><td>LastName</td><td>9-9-9</td><td>Uranus</td></tr>
<tr><td>10</td><td>Customer10</td><td>LastName</td><td>10-10-10</td><td>Neptune</td></tr>
</tbody>
</table>
</div>
注意:テーブルは、「table-holder」に等しいクラス属性を持つDIVにラップされます。
以下は、htmlページヘッダーに追加したJQueryスクリプトです。
<script src="../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
//create var for table holder
var originalTableHolder = $(".table-holder");
// set the table holder's with
originalTableHolder.width($('table', originalTableHolder).width() + 17);
// Create a clone of table holder DIV
var clonedtableHolder = originalTableHolder.clone();
// Calculate height of all header rows.
var headerHeight = 0;
$('thead', originalTableHolder).each(function (index, element) {
headerHeight = headerHeight + $(element).height();
});
// Set the position of cloned table so that cloned table overlapped the original
clonedtableHolder.css('position', 'relative');
clonedtableHolder.css('top', headerHeight + 'px');
// Set the height of cloned header equal to header height only so that body is not visible of cloned header
clonedtableHolder.height(headerHeight);
clonedtableHolder.css('overflow', 'hidden');
// reset the ID attribute of each element in cloned table
$('*', clonedtableHolder).each(function (index, element) {
if ($(element).attr('id')) {
$(element).attr('id', $(element).attr('id') + '_Cloned');
}
});
originalTableHolder.css('border-bottom', '1px solid #aaa');
// Place the cloned table holder before original one
originalTableHolder.before(clonedtableHolder);
});
</script>
最後に、少し色付けをするためのCSSクラスを以下に示します。
.table-holder
{
height:200px;
overflow:auto;
border-width:0px;
}
.customerTable thead
{
background: #4b6c9e;
color:White;
}
したがって、このロジックの全体的な考え方は、テーブルをテーブルホルダーdivに配置し、ページが読み込まれたときにクライアント側でそのホルダーのクローンを作成することです。次に、クローンホルダー内のテーブルの本体を非表示にし、残りのヘッダー部分を元のヘッダーの上に配置します。
同じソリューションがasp:gridviewでも機能します。gridviewでこれを実現するには、さらに2つの手順を追加する必要があります。
WebページのgridviewオブジェクトのOnPrerenderイベントで、ヘッダー行のテーブルセクションをTableHeaderに設定します。
if (this.HeaderRow != null)
{
this.HeaderRow.TableSection = TableRowSection.TableHeader;
}
グリッドをにラップします<div class="table-holder"></div>
。
注:ヘッダーにクリック可能なコントロールがある場合、複製されたヘッダーで発生したイベントを元のヘッダーに渡すために、さらにjQueryスクリプトを追加する必要がある場合があります。このコードは、jmosbechによって作成されたjQueryスティッキーヘッダープラグインですでに使用可能です