JSFiddle - React, Tailwind, and code Playground
by tonyleeper
HTML
<section>
<table>
<thead>
<tr>
<th>
<span>one</span>
</th>
<th>
<span>two</span>
</th>
<th>
<span>three</span>
</th>
<th>
<span>four</span>
</th>
<th>
<span>five</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>one fine day in the middle of the night, two dead men got up to fight. Back to back they faced each other, drew their swords and shot each other.</td>
<td>now is the time for all good men to come to the aid of the party.</td>
<td>the quick brown fox jumps over the lazy dog.</td>
<td>The five boxing wizards jump quickly.</td>
<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</td>
</tr>
<tr>
<td>one fine day in the middle of the night, two dead men got up to fight. Back to back they faced each other, drew their swords and shot each other.</td>
<td>now is the time for all good men to come to the aid of the party.</td>
<td>the quick brown fox jumps over the lazy dog.</td>
<td>The five boxing wizards jump quickly.</td>
<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,...
CSS
html, body {
height: 100%;
font-family: arial;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
section {
display: block;
width: 100%;
height: 100%;
position: relative;
overflow:hidden;
}
table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
text-align: left;
}
thead {
border-top: 1px solid gray;
border-bottom: 1px solid gray;
}
tbody {
overflow-y: auto;
position: absolute;
left: 0;
top: 32px;
bottom: 0;
}
th {
width: 1%;
border-left: 1px solid gray;
overflow: visible;
background-color: darkblue;
color: #fff;
}
td {
border-bottom: 1px solid gray;
border-left: 1px solid gray;
word-break: break-all;
}
.th-relative > span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
padding: 5px;
}
.th-relative {
position: relative;
}
.drag-handle {
position: absolute;
cursor: col-resize;
width: 10px;
right: -5px;
height: 100%;
top: 0;
z-index: 1;
/* otherwise cursor won't change on overflow part - we could instead add two drag handles at left and right sides but will be a bit more complex logic */
}
JavaScript
/**
jquery table plugin POC - scrollable tbody and resizable columns
*/
(function ($) {
var normalizeEvent = function (event) {
// "normalize" the event so that the passed in drag handler doesn't have to worry about
if (false) {
event.pageX = event.originalEvent.touches[0].pageX;
event.pageY = event.originalEvent.touches[0].pageY;
event.clientX = event.originalEvent.touches[0].clientX;
event.clientY = event.originalEvent.touches[0].clientY;
}
return event;
};
$.fn.draggable = function (onDrag, onDragStart, onDragEnd) {
var $document = $(document);
return this.each(function () {
var element = this;
$(this).on("mousedown touchstart", function (event) {
event = normalizeEvent(event);
if (typeof onDragStart === "function") {
if (!onDragStart.call(element, event)) {
return false;
}
}
element.dragging = true;
$(element).addClass("dragging");
// prevent scrolling on touch devices, and also text selection icon in Chrome
return false;
});
$document.on("mouseup touchend", function (event) {
if (element.dragging) {
element.dragging = false;
$(element).removeClass("dragging");
if (typeof onDragEnd === "function") {
onDragEnd.call(element, event);
}
}
});
$document.on("mousemove touchmove", function (event) {
if (element.dragging) {
// throttle mousemove and touchmove events to 40 per second
var now = Date.now();
if (!element.lastMoveTick || now - element.lastMoveTick > 25) {
...