Prototype: generate only visible columns of a scrollable table
by Sergei Sokolov
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="wrapper">
<div id="container"></div>
<div class="buttons">
<button id="btn-left" @click='stepLeft'>←</button>
<button id="btn-right" @click="stepRight">→</button>
</div>
</div>
CSS
#wrapper{
width:175px;
margin: 0 auto;
}
#container {
position:relative;
width:95px;
height:45px;
border:1px solid grey;
padding-top:5px;
}
.box {
position:absolute;
width:40px;
height:40px;
background:#CCC;
transition: left 0.8s;
}
.buttons{
width:95px; height:10px;
position:relative;
}
button {position:absolute; top:5px}
#btn-right{right:0}
JavaScript
/**
prototype for a UI
TODO: throttle commands to respect animation time.
*/
const d = document;
const N = 2; // visible
const boxes = []; // N+2
var c;
d.addEventListener('keydown', function(e){
if(e.key == 'ArrowRight') stepRight();
if(e.key == 'ArrowLeft') stepLeft();
});
const Box = Vue.component('box', {
template: `<div class="box">{{ title }}</div>`,
props: ['title']
});
const vm = new Vue({
el: '#wrapper',
data: {
items: ['a','b','c','d','e','f','g','h','i','j','k'],
pos: 0
},
methods: {
stepLeft: function(){this.move(-1)},
stepRight: function(){this.move(1)},
move: function(inc) {
if(this.pos <= 0 && inc < 0 ) return;
if(this.pos >= this.items.length && inc > 0 ) return;
this.pos += inc;
}
},
mounted: function() {
c = d.getElementById('container');
for(let i=0; i<N+2;i++) {
let el = d.createElement('div');
c.appendChild(el);
let b = new Box({
propsData:{title: this.items[i]},
el:el
});
boxes.push(b.$el);
}
update(); // place
}
});
function init() {
for(let i=0; i<N+2; i++) {
let el = d.createElement('div');
el.className = "box";
el.style.left = '' + (-45+5+i*45) + 'px';
el.innerText = i;
c.appendChild(el);
boxes.push(el);
}
}
function update(){
for(let i=0; i<boxes.length;i++){
boxes[i].style.left = '' + (-45+5+i*45) + 'px';
}
}
function stepLeft() {
boxes.shift().remove(); // delete leftmost
boxes.push(createBox());
update();
}
function stepRight() {
boxes.pop().remove(); // delete leftmost
boxes.unshift(createBox());
update();
}
function createBox(title) {
if(!title) title = Math.floor(0xFF * Math.random())
.toString(16).toUpperCase();
let el = d.createElement('div');
el.className = "box";
el.innerText = title;
c.appendChild(el);
return el;
}