I am trying to implement a calendar list view like the iOS one. Basically, what I am doing now is to loop through my array of events. If it is a new date, print a date header, else print the calendar event. I want to make the DATE HEADER rows sticky until they get "scrolled away".
How can I achieve that? I see lots of examples on sticky headers but there's no actual one that applies this "sticky" feature to table rows only. My <table
is also put within its own scrollable fixed height and I want the header to stick at the top of the <div>
instead of at top:0;
I have put my code into a pen at and now I am left with fixing the colspan
because my <td>
doesnt span across the cells, and getting the <tr>
to stick at the top of the <div>
.
I am trying to implement a calendar list view like the iOS one. Basically, what I am doing now is to loop through my array of events. If it is a new date, print a date header, else print the calendar event. I want to make the DATE HEADER rows sticky until they get "scrolled away".
How can I achieve that? I see lots of examples on sticky headers but there's no actual one that applies this "sticky" feature to table rows only. My <table
is also put within its own scrollable fixed height and I want the header to stick at the top of the <div>
instead of at top:0;
I have put my code into a pen at http://codepen.io/anon/pen/zxpkr and now I am left with fixing the colspan
because my <td>
doesnt span across the cells, and getting the <tr>
to stick at the top of the <div>
.
- Any html - css - javascript code to provide ? Also, your codepen example is NOT about table. Those are dividers. div's. Anyway, go take a look at : imakewebthings./jquery-waypoints/shortcuts/sticky-elements – Milche Patern Commented Jul 8, 2013 at 17:18
- You can also take a look at : stackoverflow./questions/9590087/… – Milche Patern Commented Jul 8, 2013 at 17:24
- Yeah I realised my tags (div and table and tr and td) didnt show initially until I enclosed them in code tags. – chongzixin Commented Jul 9, 2013 at 2:37
- @user1258600 Your issue is a Client Side issue, so you have to supply your PHP's HTML output in your code example. Modify this jsfiddle example and jsfiddle/dCKmL – SaidbakR Commented Jul 10, 2013 at 22:48
- @sємsєм my code is now on CodePen @ codepen.io/anon/pen/zxpkr ! :) – chongzixin Commented Jul 11, 2013 at 13:57
3 Answers
Reset to default 2I had to wrap the scrollable div with a container div and play with the if statements a bit, but it works.
Working Example
JS
function stickyTitles(stickies) {
this.load = function () {
stickies.each(function () {
var thisSticky = jQuery(this).wrap('<div class="followWrap" />');
thisSticky.parent().height(thisSticky.outerHeight());
jQuery.data(thisSticky[0], 'pos', thisSticky.offset().top);
});
};
this.scroll = function () {
stickies.each(function (i) {
var thisSticky = jQuery(this),
nextSticky = stickies.eq(i + 1),
prevSticky = stickies.eq(i - 1),
pos = jQuery.data(thisSticky[0], 'pos'),
h = $('.mytable').offset().top;
if (pos <= jQuery('.mytable').scrollTop() + h) {
thisSticky.addClass("fixed");
if (nextSticky.length > 0 && jQuery('.mytable').scrollTop() + h >= jQuery.data(thisSticky[0], 'pos') - prevSticky.outerHeight()) {
thisSticky.addClass("absolute").css("top", jQuery.data(nextSticky[0], 'pos') - $('.mytable').scrollTop() - prevSticky.outerHeight() - h);
}
} else {
thisSticky.removeClass("fixed");
if (prevSticky.length > 0 && jQuery('.mytable').scrollTop() + h <= jQuery.data(thisSticky[0], 'pos') - prevSticky.outerHeight()) {
prevSticky.removeClass("absolute").removeAttr("style");
}
}
});
};
}
jQuery(document).ready(function () {
var newStickies = new stickyTitles(jQuery(".followMeBar"));
newStickies.load();
jQuery('.mytable').on("scroll", function () {
newStickies.scroll();
});
});
CSS
body {
height:2000px;
margin: 0;
background: #333;
color: #fff;
overflow: auto;
}
table {
width: 100%;
}
table tr {
height: 100px;
}
.followMeBar {
display: block;
background: #222;
border-bottom: solid 1px #111;
border-top: solid 1px #444;
position: relative;
z-index: 1;
width: 200%;
}
.followMeBar.fixed {
position: absolute;
top: 0;
width: 90%;
z-index: 0;
}
.followMeBar.fixed.absolute {
position: absolute;
}
.mytable {
overflow-y: scroll;
height: 250px;
}
#hidden {
overflow:hidden;
position:absolute;
width:100%;
}
HTML
<h1>Test</h1>
<p>My table in a div below...</p>
<div id="hidden">
<div class='mytable'>
<table>
<tr class='followMeBar'>
<td colspan="4">12-07-2013</td>
</tr>
<tr>
<td>4:35 PM</td>
<td>1729</td>
<td>2</td>
<td>jack</td>
</tr>
<tr>
<td>4:40 PM</td>
<td>KSKS</td>
<td>4</td>
<td>jason</td>
</tr>
<tr>
<td>5:35 PM</td>
<td>1714</td>
<td>4</td>
<td>raymond</td>
</tr>
etc...
</table>
</div>
</div>
Please note that this method was based off of this answer, I had to adjust things a bit to make it work for a scrollable div, but I want to give credit where credit is due.
Replaced all div
s with a table and tr
s, added some styling, and it works :P
Code: Codepen
Altough it wraps up all header tr
s with a div
. It's not really allowed by the specs but it works.
Instead of making a row absolute position, which btw may not work very well across browsers, I would rather have a table at the top which works as the table head (and sticks to the top of the parent div) and have the data table scroll below it.
You dont even need to use jQuery for this!
http://jsbin./ucevuy/1/edit
* {
margin:0;
padding:0;
}
div {
border:solid red;
height:300px;
overflow:auto;
}
table {
width:400px;
}
td {
border:solid black 1px;
width:50%;
}
.head {
position:absolute;
top:0;
background-color:#fff;
}
.data {
margin-top:20px;
}