Pure CSS/HTML/Javascript 2D Scrollable table with fixed column and header - javascript

I have a large table which might need to scroll both horizontally and vertically. I have seen lots of solutions for this but haven't found one that works that doesn't rely on jscript or similar. It seems like it should be doable but I've come up with problems. I think I can get the header row ok, but I am having trouble with the fixed column. I can't seem to get my body to extend beyond the viewport and my code is rendering very differently on IE8 and Firefox.
Can anyone give me any guidance?
<html>
<head>
<script type="text/javascript">
function windowwidth(){
var myWidth = 0;
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && ( document.documentElement.clientWidth ||document.documentElement.clientHeight ) ) {
myWidth = document.documentElement.clientWidth;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
myWidth = document.body.clientWidth;
}
return myWidth ;
}
function windowheight(){
var myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth ||document.documentElement.clientHeight ) ) {
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
myHeight = document.body.clientHeight;
}
return myHeight ;
}
function pageloader(){
var leftwidth=document.getElementById('left').offsetWidth;
document.getElementById('right').style.marginLeft=leftwidth+'px';
}
</script>
<style>
div{ border:solid; }
.left{ position:absolute; }
.right{ position:float-left; margin-left:50px;}
table,td{ border:solid; }
td{ width:200px; }
tr{ height:50px; }
</style>
</head>
<body onload='pageloader();'>
<div name=left id=left class=left>
<table>
<tr><td>0</td></tr>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td>4</td></tr>
<tr><td>5</td></tr>
<tr><td>6</td></tr>
<tr><td>7</td></tr>
<tr><td>8</td></tr>
<tr><td>9</td></tr>
</table>
</div>
<div name=right id=right class=right>
<table>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
</div>
</body>
</html>

I worked on it further though and came up with this solution. It works pretty well and is even pretty flexible. I think it's the best solution I've seen. Please let me know if you know of something better or know of a way to improve it.
The only thing I've found impossible to fix is the vertical-align which has to be top. Does anyone know of a decent, simple solution that makes IE8 respect vertical-align center for a td with a height?
Here is the demo: http://maymay.de/demos/table.html
And here is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript">
function getStyle(oElm, strCssRule){
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle){
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
}
function pageloader(){
// get sizes of boxes
var leftys=document.getElementById('left').getElementsByTagName('td');
var lefty=leftys[0];
var barys=document.getElementById('topbar').getElementsByTagName('td');
var bary=barys[0];
var boxys=document.getElementById('topleft').getElementsByTagName('td');
var boxy=boxys[0];
var leftwidth=lefty.offsetWidth;
var topheight=bary.offsetHeight;
var boxwidth=boxy.offsetWidth;
var boxheight=boxy.offsetHeight;
if(topheight>boxheight){
var newtopheight=topheight;
var newinnerheight=bary.clientHeight-parseInt(getStyle(bary, "padding-top"))-parseInt(getStyle(bary, "padding-bottom"));
}else{
var newtopheight=boxheight;
var newinnerheight=boxy.clientHeight-parseInt(getStyle(boxy, "padding-top"))-parseInt(getStyle(boxy, "padding-bottom"));
}
// set new width for left column
if(leftwidth>boxwidth){
var newleftwidth=leftwidth;
var newinnerwidth=lefty.clientWidth-parseInt(getStyle(lefty, "padding-left"))-parseInt(getStyle(lefty, "padding-right"));
}else{
var newleftwidth=boxwidth;
var newinnerwidth=boxy.clientWidth-parseInt(getStyle(boxy, "padding-left"))-parseInt(getStyle(boxy, "padding-right"));
}
// apply widths and heights and margins
// alert ("newleftwidth: "+newleftwidth+" newtopheight: "+newtopheight+"\nnewinnerheight: "+newinnerheight+" newinnerwidth: "+newinnerwidth);
boxy.style.height=newinnerheight+'px';
bary.style.height=newinnerheight+'px';
boxy.style.width=newinnerwidth+'px';
lefty.style.width=newinnerwidth+'px';
document.getElementById('left').style.marginTop=newtopheight+'px';
document.getElementById('topbar').style.marginLeft=newleftwidth+'px';
document.getElementById('right').style.marginLeft=newleftwidth+'px';
document.getElementById('right').style.marginTop=newtopheight+'px';
// fix column widths and rowheights
colsync();
rowsync();
calcright();
// alert ("leftwidth: "+newleftwidth+" topheight: "+newtopheight);
}
function scrolling(){
if (window.pageXoffset) {
var xscroll=window.pageXoffset;
} else if (document.body.scrollLeft) {
var xscroll=document.body.scrollLeft;
} else if (document.body.parentElement.scrollLeft) {
var xscroll=document.body.parentElement.scrollLeft;
} else if (document.body.parentNode.scrollLeft) {
var xscroll=document.body.parentNode.scrollLeft;
} else {
var xscroll=0;
}
if (window.pageYoffset) {
var yscroll=window.pageYOffset;
} else if (document.body.scrollTop) {
var yscroll=document.body.scrollTop;
} else if (document.body.parentElement.scrollTop) {
var yscroll=document.body.parentElement.scrollTop;
} else if (document.body.parentNode.scrollTop) {
var yscroll=document.body.parentNode.scrollTop;
} else {
var yscroll=0;
}
var leftwidth=document.getElementById('left').offsetWidth;
var topheight=document.getElementById('topbar').offsetHeight;
var newleftmargin=leftwidth-xscroll;
var newtopmargin=topheight-yscroll;
document.getElementById('left').style.top=-yscroll+'px';
document.getElementById('topbar').style.left=-xscroll+'px';
}
function info(){
}
function calcright(){
// resize page to shrink to fit
var rchildrenr = document.getElementById('right').getElementsByTagName('tr');
var rchildrend = rchildrenr[1].getElementsByTagName('td');
var rcols = rchildrend.length;
var rsum = 0;
for (i=0;i<rchildrend.length;i++) {
rsum = rchildrend[i].offsetWidth;
}
document.getElementById('topbar').style.width=rchildrenr[1].offsetWidth+'px';
document.getElementById('right').style.width=rchildrenr[1].offsetWidth+'px';
}
function colsync(){
var topcells = document.getElementById('topbar').getElementsByTagName('td');
var rightrows = document.getElementById('right').getElementsByTagName('tr');
var rightcells = rightrows[1].getElementsByTagName('td');
var mypads=0;
for (i=0;i<topcells.length;i++) {
if (topcells[i].offsetWidth>rightcells[i].offsetWidth) {
mypads=parseInt(getStyle(rightcells[i], "padding-left"))+parseInt(getStyle(rightcells[i], "padding-right"));
rightcells[i].style.width=topcells[i].clientWidth-mypads+'px';
}else{
mypads=parseInt(getStyle(topcells[i], "padding-left"))+parseInt(getStyle(topcells[i], "padding-right"));
topcells[i].style.width=rightcells[i].clientWidth-mypads+'px';
}
}
}
function rowsync(){
var leftcells = document.getElementById('left').getElementsByTagName('td');
var rightrows = document.getElementById('right').getElementsByTagName('tr');
var mypads=0;
for (i=0;i<leftcells.length;i++) {
rightcells=rightrows[i].getElementsByTagName('td');
if (leftcells[i].offsetHeight>rightcells[i].offsetHeight) {
mypads=parseInt(getStyle(rightcells[i], "padding-top"))+parseInt(getStyle(rightcells[i], "padding-bottom"));
rightcells[i].style.height=leftcells[i].clientHeight-mypads+'px';
// if (i==1) alert (leftcells[i].clientHeight);
}else{
mypads=parseInt(getStyle(leftcells[i], "padding-top"))+parseInt(getStyle(leftcells[i], "padding-bottom"));
leftcells[i].style.height=rightcells[i].clientHeight-mypads+'px';
// if (i==1) alert (leftcells[i].clientHeight);
}
}
}
window.onscroll = scrolling;
</script>
<style>
body{ margin:0; }
div{ border:none; }
.left{ position:fixed; background-color:White; z-index:0;}
.topleft{ position:fixed; background-color:White; z-index:1;}
.topbar{ position:fixed; background-color:White; width:1000000px; z-index:0;}
.right{ position:absolute; margin-left:50px; width:1000000px; z-index:-1;}
table{ border:none; border-spacing:0px;}
td{ border:solid; border-width:1px; width:5px; padding:2px; vertical-align:top; text-align:center;}
tr{ height:5px; }
</style>
</head>
<body onload='pageloader();'>
<div name=topleft id=topleft class=topleft onclick=info(); >
<table id=tabletable>
<tr><td>Fixed Block</td></tr>
</table>
</div>
<div name=left id=left class=left>
<table>
<tr><td>Row-0</td></tr>
<tr><td>Row-1</td></tr>
<tr><td>Row-2</td></tr>
<tr><td>Row-3</td></tr>
<tr><td>Row-4</td></tr>
<tr><td>Row-5</td></tr>
<tr><td>Row-6</td></tr>
<tr><td>Row-7</td></tr>
<tr><td>Row-8</td></tr>
<tr><td>Row-9</td></tr>
</table>
</div>
<div name=topbar id=topbar class=topbar>
<table>
<tr>
<td>Cola</td>
<td>Colb</td>
<td>Colc</td>
<td>Cold</td>
<td>Cole</td>
<td>Colf</td>
<td>Colg</td>
<td>Colh</td>
<td>Coli</td>
<td>Colj</td>
</tr>
</table>
</div>
<div name=right id=right class=right>
<table>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
</tr>
<tr>
<td>20</td>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
<td>29</td>
</tr>
<tr>
<td>30</td>
<td>31</td>
<td>32</td>
<td>33</td>
<td>34</td>
<td>35</td>
<td>36</td>
<td>37</td>
<td>38</td>
<td>39</td>
</tr>
<tr>
<td>40</td>
<td>41</td>
<td>42</td>
<td>43</td>
<td>44</td>
<td>45</td>
<td>46</td>
<td>47</td>
<td>48</td>
<td>49</td>
</tr>
<tr>
<td>50</td>
<td>51</td>
<td>52</td>
<td>53</td>
<td>54</td>
<td>55</td>
<td>56</td>
<td>57</td>
<td>58</td>
<td>59</td>
</tr>
<tr>
<td>60</td>
<td>61</td>
<td>62</td>
<td>63</td>
<td>64</td>
<td>65</td>
<td>66</td>
<td>67</td>
<td>68</td>
<td>69</td>
</tr>
<tr>
<td>70</td>
<td>71</td>
<td>72</td>
<td>73</td>
<td>74</td>
<td>75</td>
<td>76</td>
<td>77</td>
<td>78</td>
<td>79</td>
</tr>
<tr>
<td>80</td>
<td>81</td>
<td>82</td>
<td>83</td>
<td>84</td>
<td>85</td>
<td>86</td>
<td>87</td>
<td>88</td>
<td>89</td>
</tr>
<tr>
<td>90</td>
<td>91</td>
<td>92</td>
<td>93</td>
<td>94</td>
<td>95</td>
<td>96</td>
<td>97</td>
<td>98</td>
<td>99</td>
</tr>
</table>
</div>
</body>
</html>

Related

Alternating color rows based on values of cells

I'd like to have a table with alternating colors of rows but rows with the same value should have unitary background color. Can I achieve such an effect with CSS?
Example:
JQuery
(feel free to simplify and edit this)
$(function() {
let elems = $('tr:not(".head")');
let count = 0;
for (let i=0; i<elems.length; i++) {
let el = $(elems[i]),
prev = $(elems[i-1]);
let isEven = (count % 2 == 0);
if (isEven) {
el.css('background', 'red');
} else {
el.css('background', 'yellow');
}
if (el.text() == prev.text()) {
let clr = prev.css('background');
el.css('background', clr);
} else {
count++;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="head">
<th>One</th>
<th>Two</th>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
</tr>
</table>

Drawing arrows above HTML

I have an html table and I want to draw an arrow from one cell to an other cell. For example like this:
How could this be done?
Example HTML:
<html>
<body>
<table>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td id="end">9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td id="start">0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
</body>
</html>
If you resize the browser, the arrow should stay on the (new) start/end position.
With a bit of JavasSript and CSS you can achieve this without canvas or SVG. Here is an example:
function getPosition(el) {
return {
x: el.offsetLeft + el.offsetWidth / 2,
y: el.offsetTop + el.offsetHeight / 2
};
}
function getDistance(a, b) {
const from = getPosition(a);
const to = getPosition(b);
return {
//https://stackoverflow.com/a/17628488/529024
distance: Math.hypot(from.x - to.x, from.y - to.y),
angle: Math.atan2(to.x - from.x, from.y - to.y) * 180 / Math.PI,
position: {
start: from,
end: to
}
}
}
function init(){
// Get values and elements then set style
const values = getDistance(
document.getElementById("start"),
document.getElementById("end")
);
let wrapper = document.getElementById('wrapper');
let arrow = document.getElementById('arrow');
let bottom = wrapper.offsetHeight - values.position.start.y;
arrow.style.height = values.distance + "px";
arrow.style.transform = `rotate(${values.angle}deg)`;
arrow.style.bottom = bottom + "px";
arrow.style.left = values.position.start.x + "px";
}
init();
window.addEventListener('resize', function(){
init();
});
#wrapper {
position: relative;
left: 50px;
top: 100px;
}
#arrow {
position: absolute;
width: 2px;
background-color: red;
transform-origin: bottom center;
}
#arrow::before {
position: absolute;
height: 0px;
width: 0px;
border: 6px solid transparent;
border-bottom: 8px solid red;
content: "";
bottom: 100%;
left: 50%;
transform: translateX(-50%);
}
<div id='wrapper'>
<div id='arrow'></div>
<table>
<tr>
<td >0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td id="end">9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td id="start">0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
</div>
You can use my solution not complete draw arrow yet,
let create a canvas and draw a line from two points, based on calculate of start and end point.
Example running: https://jsfiddle.net/tabvn/uk7hsj3a
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
</head>
<body>
<table id="my-table">
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td id="end">9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td id="start">0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
<script type="text/javascript">
var table = document.getElementById('my-table')
var startElement = document.getElementById('start')
var endElement = document.getElementById('end')
var startPoint = {x: startElement.offsetLeft + table.offsetLeft, y: startElement.offsetTop + table.offsetTop}
var endPoint = {x: endElement.offsetLeft + table.offsetLeft, y: endElement.offsetTop + table.offsetTop}
var canvas = document.createElement('canvas')
canvas.width = table.clientWidth
canvas.height = table.clientHeight
canvas.style.position = 'absolute'
canvas.style.top = startPoint.y < endPoint.y ? startPoint.y + 'px' : endPoint.y + 'px'
canvas.style.left = startPoint.x < endPoint.x ? startPoint.x + 'px' : endPoint.x + 'px'
var ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.fillStyle = 'red'
ctx.moveTo(startPoint.x - (startElement.clientWidth / 2), startPoint.y)
ctx.lineTo(endPoint.x - (endElement.clientWidth / 2), endPoint.y)
ctx.stroke()
document.body.insertBefore(canvas, table, 30)
</script>
</body>
</html>
This is how I would do it:
The svg element uses the size of the table for the viewBox value.
You are calculating the size and the position of the cells you need to correlate and use this position to draw the line. A marker is used for the tip of the arrow.
Please resize the window:
let cells = Array.from(document.querySelectorAll("td"));
// index of cells to be correlated
let n1 = 90;
let n2 = 9;
// a function to draw the arrow
function drawArrow(){
//get the size of the table
let size = theTable.getBoundingClientRect();
//set the viewBox attribute for the svg element
theSVG.setAttributeNS(null, "viewBox", `0 0 ${size.width} ${size.height}`)
//get the size and the position of the cells
let c1 = cells[n1].getBoundingClientRect();
let c2 = cells[n2].getBoundingClientRect();
//set the x1, y1, x2,y2 attributes of the line
theLine.setAttributeNS(null,"x1",`${c1.left + c1.width/2}`);
theLine.setAttributeNS(null,"y1",`${c1.top + c1.height/2}`);
theLine.setAttributeNS(null,"x2",`${c2.left + c2.width/2}`);
theLine.setAttributeNS(null,"y2",`${c2.top + c1.height/2}`);
}
drawArrow()
window.setTimeout(function() {
drawArrow()
window.addEventListener('resize', drawArrow, false);
}, 15);
body {
margin: 0;
padding: 0;
}
table,svg{
width: 100%;
border-collapse: collapse;
margin: 0;
position:absolute;
}
td {
border: 1px solid #d9d9d9;
padding: 0.5em;
text-align: center;
}
svg{background:rgba(0,0, 255,.5)}
<table id="theTable">
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td id="end">9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
<tr><td id="start">0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><tr>
</table>
<svg id="theSVG">
<defs>
<marker id="arrow" markerWidth="6" markerHeight="12" refX="8" refY="6" orient="auto">
<path d="M 0 0 L 8 6 L 0 12" />
</marker>
</defs>
<line id="theLine" marker-end="url(#arrow)" stroke="black" />
</svg>
UPDATE:
Since someone commented that on resize the arrow is losing it's position I am adding a gif:
Javascript solution:
drawLine();
function drawLine () {
var table = document.getElementById('my-table')
var startElement = document.getElementById('start')
var endElement = document.getElementById('end')
let arrowRadius = 10;
let xStart = null;
let xEnd = null;
if (startElement.offsetLeft > endElement.offsetLeft) {
xStart = startElement.offsetLeft + (arrowRadius/2);//to add padding just add more wherever theres this pattern
xEnd = endElement.offsetLeft + endElement.offsetWidth / 2;
} else if (startElement.offsetLeft < endElement.offsetLeft) {
xStart = startElement.offsetLeft + startElement.offsetWidth - (arrowRadius/2);
xEnd = endElement.offsetLeft;
} else {
xStart = startElement.offsetLeft + startElement.offsetWidth / 2;
xEnd = endElement.offsetLeft + endElement.offsetWidth / 2;
}
let yStart = null;
let yEnd = null;
if (startElement.offsetTop > endElement.offsetTop) {
yStart = startElement.offsetTop + (arrowRadius/2);
yEnd = endElement.offsetTop + endElement.offsetHeight + (arrowRadius/2);
} else if (startElement.offsetTop < endElement.offsetTop) {
yStart = startElement.offsetTop + startElement.offsetHeight - (arrowRadius/2);
yEnd = endElement.offsetTop - (arrowRadius/2);
} else {
yStart = startElement.offsetTop + startElement.offsetHeight / 2;
yEnd = endElement.offsetTop + endElement.offsetHeight / 2;
}
let coordBegin = {
x: xStart,
y: yStart
};
let coordEnd = {
x: xEnd,
y: yEnd
};
var canvas = document.createElement('canvas')
canvas.width = table.offsetWidth
canvas.height = table.offsetHeight
canvas.style.position = 'absolute'
var ctx = canvas.getContext('2d')
drawArrowhead(ctx, coordBegin, coordEnd, arrowRadius);
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.fillStyle = 'red'
ctx.moveTo(coordBegin.x, coordBegin.y)
ctx.lineTo(coordEnd.x, coordEnd.y)
ctx.stroke()
document.body.insertBefore(canvas, table)
}
function drawArrowhead(context, from, to, radius) {
var x_center = to.x;
var y_center = to.y;
var angle;
var x;
var y;
context.beginPath();
angle = Math.atan2(to.y - from.y, to.x - from.x)
x = radius * Math.cos(angle) + x_center;
y = radius * Math.sin(angle) + y_center;
context.moveTo(x, y);
angle += (1.0/3.0) * (2 * Math.PI)
x = radius * Math.cos(angle) + x_center;
y = radius * Math.sin(angle) + y_center;
context.lineTo(x, y);
angle += (1.0/3.0) * (2 * Math.PI)
x = radius *Math.cos(angle) + x_center;
y = radius *Math.sin(angle) + y_center;
context.lineTo(x, y);
context.closePath();
context.fillStyle = 'red';
context.fill();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
</head>
<body>
<table id="my-table">
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td id="end">9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td id="start">0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
</body>
</html>
You can use an SVG element and css styles for absolute position overlaying your table. And get the start and end point by JavaScript DOM API like getBoundingClientRect()
Here is a demo. (Made with Angular, but you can use it everywhere. Pure JavaScript example see below.)
const startElement = document.querySelector('#start');
const endElement = document.querySelector('#end');
const startRect = startElement.getBoundingClientRect();
const endRect = endElement.getBoundingClientRect();
const startX = startRect.right;
const startY = startRect.top;
const endX = endRect.left;
const endY = endRect.bottom;
You can change the start and end dynamically. You only have to reinvoke the method to get the positions. Note that I use left, top, right, button to place the arrow on the edge of the element. You could compute the center point or the edge by comparing the both positions.
And you have to place the svg over the table. You can do this by set css position: absolute; left: 0; top: 0. But note, that your parent should also have the position attribute. e.g. position: relative.
Update: Here is a pure JavaScript demo. Click on the left to view all files and select index.js to view the JS stuff. (like in VS Code).
Complete code:
<table style="position: absolute; left: 0; top: 0;">
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td id="end">9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td id="start">0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<svg style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 1">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="5" refY="3" orient="auto"
markerUnits="strokeWidth" viewBox="0 0 20 20">
<path d="M0,0 L0,6 L9,3 z" fill="#f00" />
</marker>
</defs>
<line id="svg-line" stroke="#f00" stroke-width="5"
marker-end="url(#arrow)" />
</svg>
</table>
<script>
const svgLine = document.querySelector('#svg-line');
const startElement = document.querySelector("#start");
const endElement = document.querySelector("#end");
const startRect = startElement.getBoundingClientRect();
const endRect = endElement.getBoundingClientRect();
const startX = startRect.right;
const startY = startRect.top;
const endX = endRect.left;
const endY = endRect.bottom;
svgLine.setAttribute('x1', startX);
svgLine.setAttribute('y1', startY);
svgLine.setAttribute('x2', endX);
svgLine.setAttribute('y2', endY);
</script>
Just copy the code above in a new empty html file and run it in your browser.
Btw. You can also do this with a canvas. (alternative for svg)
You need to put the table in a div and give a property, position: relative
Then write HTML for the arrow (use an image if you want to) and give it a property of absolute and then style it as you want using, top, left, right..
Read more about position properties here https://www.w3schools.com/css/css_positioning.asp

Change the colour of the 2nd column by comparing it with the 1st column

enter image description here
If there is a change in the number in the column, its colour should get change as well.
There are 7 columns.
Compare 1st column with the second. If the numbers are changed, its colour should get change.
Example in first row "134", "139" then "139" value colour should get change.
In second row "4" "4" is repeated, then its colour should not get change.
<table style="width:80%" id="customers" align="center">
<tr>
<th style="background-color:white;" colspan="2"><input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search Here" title="Type in a name"></th>
<th colspan="7"> asfdasdf</th>
</tr>
<tr>
<th colspan="2"><select class="ui dropdown" id="myselection">
<option value="One">Readvon</option>
<option value="Two">sdctry</option>
<option value="Three">scv</option>
<option value="four">sdv</option>
</select></th>
<th>Nov_2013</th>
<th>March_2014</th>
<th>Dec_2015</th>
<th>Nov_2017</th>
<th>April_2018</th>
<th>Feb_2019</th>
<th>April_2019</th>
</tr>
</table>
<div id="showOne">
<table style="width:80%" id="customers" align="center">
<tr>
<td colspan='2' style='color:red'>Total</td>
<td>134</td>
<td>139</td>
<td>137</td>
<td>158</td>
<td>144</td>
<td>146</td>
<td>140</td>
<tr>
<td colspan='2'>Aadc</td>
<td>0</td>
<td>4</td>
<td>4</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>4</td>
<tr>
<td colspan='2'>Asdvacific</td>
<td>48</td>
<td>45</td>
<td>33</td>
<td>36</td>
<td>33</td>
<td>34</td>
<td>33</td>
<tr>
<td colspan='2'>Eafcdpe</td>
<td>45</td>
<td>42</td>
<td>46</td>
<td>53</td>
<td>48</td>
<td>52</td>
<td>50</td>
<tr>
<td colspan='2'>Inasdca</td>
<td>0</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>3</td>
<tr>
<td colspan='2'>MsCDNA</td>
<td>4</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>6</td>
<td>6</td>
<tr>
<td colspan='2'>NortScerica</td>
<td>37</td>
<td>38</td>
<td>44</td>
<td>49</td>
<td>48</td>
<td>41</td>
<td>40</td>
<tr>
<td colspan='2'>SouacAmerica</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>4</td>
<td>0</td>
<td>4</td>
<td>4</td>
</tr>
</table>
</div>
</table>
You have to do something like below. Read about HTMLTableElement. You have to access rows first and then columns. Compare text in each column...
var table = document.getElementsByTagName('table');
var rows = table[0].rows
var rowsLength = rows.length;
var columns;
var columnsLength;
for (var i = 0; i < rowsLength; i++) {
columns = rows[i].cells;
columnsLength = columns.length;
// We don't need first column, as it contains the text
for (var j = 1; j < columnsLength - 1; j++) {
if (parseInt(columns[j].innerText) != parseInt(columns[j + 1].innerText)) {
columns[j + 1].style.color = 'green';
}
}
}
<table style="width:80%" id="customers" align="center">
<tr>
<td colspan='2' style='color:red'>Total</td>
<td>134</td>
<td>139</td>
<td>137</td>
<td>158</td>
<td>144</td>
<td>146</td>
<td>140</td>
</tr>
<tr>
<td colspan='2'>Aadc</td>
<td>0</td>
<td>4</td>
<td>4</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>4</td>
</tr>
<tr>
<td colspan='2'>Asdvacific</td>
<td>48</td>
<td>45</td>
<td>33</td>
<td>36</td>
<td>33</td>
<td>34</td>
<td>33</td>
</tr>
<tr>
<td colspan='2'>Eafcdpe</td>
<td>45</td>
<td>42</td>
<td>46</td>
<td>53</td>
<td>48</td>
<td>52</td>
<td>50</td>
</tr>
<tr>
<td colspan='2'>Inasdca</td>
<td>0</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>3</td>
</tr>
<tr>
<td colspan='2'>MsCDNA</td>
<td>4</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td colspan='2'>NortScerica</td>
<td>37</td>
<td>38</td>
<td>44</td>
<td>49</td>
<td>48</td>
<td>41</td>
<td>40</td>
</tr>
<tr>
<td colspan='2'>SouacAmerica</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>4</td>
<td>0</td>
<td>4</td>
<td>4</td>
</tr>
</table>

Javascript/jQuery Tables Element Grabbing [duplicate]

This question already has answers here:
get the value of any clicked td jquery
(2 answers)
Closed 4 years ago.
I have a problem, I wish to grab the value thingy in a "td"
This is my code:
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
<td>21</td>
</tr>
<tr>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
</tr>
<tr>
<td>29</td>
<td>30</td>
<td>31</td>
</tr>
</table>
I have tried giving them classes and onclick functions() but is there a way without creating a thousand or so functions and ids.
You can have onclick event handle on table (using id or class selector in jquery). See below code
$(function(){ // this is to ensure if all DOM loaded
$("#tableToRead td").on("click", function(){ // click handler for each td inside tableToRead table
var value = $(this).text();// here $(this) refer to clicked td and using .text() gives text inside td.
alert(value);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableToRead">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
<td>21</td>
</tr>
<tr>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
</tr>
<tr>
<td>29</td>
<td>30</td>
<td>31</td>
</tr>
</table>
Use event delegation: add a single listener to the table, and then examine the target of all click events. If the clicked element matches a td, get the textContent of that td:
document.querySelector('table').addEventListener('click', ({ target }) => {
if (!target.matches('td')) return;
console.log('clicked on element with textContent: ' + target.textContent);
});
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
<td>21</td>
</tr>
<tr>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
</tr>
<tr>
<td>29</td>
<td>30</td>
<td>31</td>
</tr>
</table>
(Ideally, give the one table an id so that you can select it by selecting that id, rather than using querySelector('table'), which will select the first table in your document, no matter what it is)
Hope this will help you
$('#tbl').on('click','td',function(){
var myValue= $(this).html();
var prevValue=$(this).prev('td').html();
var nextValue=$(this).next('td').html();
alert('myvalue='+myValue+', prevValue='+prevValue+',nextValue='+nextValue+'');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tbl">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
<td>21</td>
</tr>
<tr>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
</tr>
<tr>
<td>29</td>
<td>30</td>
<td>31</td>
</tr>
</table>

How to apply a carousel effect to a table in Bootstrap?

We can make table scrollable by adding table-responsive class to it, but how can we loop it so that once the loop ends, first column will follow the last column as if it is the adjacent column. (this doesn't happen when we apply marquee)
Im not sure this is what you were looking for, but it sounded like a cool idea. Heres what I came up with for a "Carousel Effect on a Table" (which is what i think you were asking). Run the code snippet to see the effect. You might need to alter the css a little to get a seamless scroll effect.
var $table = $('.table-wrapper table');
var leftTimeout, left = $('.left');
function scrollLeft(){
$('.table-wrapper').scrollLeft($('.table-wrapper').scrollLeft()-50);
$.each($table.find('tr'),function(){
$(this).children().last().detach().prependTo(this);
});
}
left.mousedown(function(){
scrollLeft();
leftTimeout = setInterval(function(){
scrollLeft();
}, 500);
return false;
});
$(document).mouseup(function(){
clearInterval(leftTimeout);
return false;
});
var rightTimeout, right = $('.right');
function scrollRight(){
$('.table-wrapper').scrollLeft($('.table-wrapper').scrollLeft()+50);
$.each($table.find('tr'),function(){
$(this).children().first().detach().appendTo(this);
});
}
right.mousedown(function(){
scrollRight();
leftTimeout = setInterval(function(){
scrollRight();
}, 500);
return false;
});
$(document).mouseup(function(){
clearInterval(rightTimeout);
return false;
});
.table-wrapper
{
border: 1px solid red;
width: 200px;
height: 150px;
overflow:hidden;
}
table
{
border: 1px solid black;
margin-right: 20px;
}
td
{
min-width: 50px;
height: 20px;
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="table-wrapper">
<table>
<tr>
<th>1h</th>
<th>2h</th>
<th>3h</th>
<th>4h</th>
<th>5h</th>
<th>6h</th>
<th>7h</th>
<th>8h</th>
<th>9h</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
</div>
<button class='left'><</button>
<button class='right'>></button>

Categories

Resources