Skip to content

Instantly share code, notes, and snippets.

@tjunussov
Last active June 28, 2017 20:34
Show Gist options
  • Save tjunussov/8313e800d79724c7fbadce3a24397250 to your computer and use it in GitHub Desktop.
Save tjunussov/8313e800d79724c7fbadce3a24397250 to your computer and use it in GitHub Desktop.
Calendar multicolumn scrollable vue
<style id="jsbin-css">
html,body {
height:300px;
width:756px;
font-family:monospace;
}
/********* reseting ************/
ul,li {
padding: 0;
margin: 0;
list-style: none;
box-sizing:border-box;
}
td {
padding:0;
}
/*********************/
.scroll {
width: 100%; height: 100%; overflow-x: scroll; position:relative;
}
.scroll_container {
position:absolute;
left:0;
right:0;
top: 0;
bottom: 0;
}
/*********CALENDAR************/
.table {
display:table;
border-spacing:0;
border-collapse:collapse;
padding:0;
margin:0;
box-sizing:border-box;
}
.labels ul, .items .decor ul:not(:last-child) {
border-right:1px solid rgba(0,0,0,0.05);
}
.items ul {
display: table-cell;
/*overflow:hidden;*/
position:relative;
}
ul > label {
display:list-item;
background-color:rgba(0,0,0,0.15);
}
.items .decor li,
.labels li,
ul > label
{
border-bottom:1px solid rgba(0,0,0,0.15);
height:var(--reservation-height);
}
.items ul {
min-width:200px;
overflow:hidden;
}
/*****************************/
.sm-calendar {
--reservation-height: 25px;
--duration : 30; /* defaul minimal duration is 30*/
--start : 1; /* minutes, start 10:00 */
--precision : 30; /*[30min] 1800 sec in 30min*/
}
.sm-calendar {
border:1px solid #ccc;
}
.sm-calendar td {
vertical-align:top;
}
/******************/
.decor, .books {
position:absolute;
height: 100%;
}
.books ul, .books li {
}
/********* FX *********/
.items li:hover {
background:rgba(255,0,0,0.5);
}
book:hover {
background:rgba(0,0,255,0.5);
}
/******************/
book {
display:inline-block;
box-sizing:border-box;
overflow: hidden;
/*max-width: 200px;*/
width: 100%;
background:#ccc;
top:calc(var(--reservation-height) * var(--start)/var(--precision));
min-height:calc(var(--reservation-height) * var(--duration)/var(--precision)); /* actual height, для плавного отрытия */
max-height:calc(var(--reservation-height) * var(--duration)/var(--precision));/* actual height */
z-index: 16;
position: absolute; /* why not ? */
opacity:0.8;
cursor:pointer;
}
/******************/
book.canceled {
opacity:0.5;
z-index:-2;
}
</style>
<html>
<body>
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<table id="sm-calendar" border="0" class="sm-calendar table" style="table-layout:fixed; width:100%;height:100%;">
<tr>
<td class="labels" style="width:50px;">
<ul>
<label>#</label>
<li v-for="t in timeRange">{{t+10}}:00</li>
</ul>
</td>
<td class="items ">
<div class="scroll">
<div class="scroll_container">
<div class="books table" style="width:100%;">
<ul v-for="r in resources">
<book v-for="b in books[r.name]" key="r.name"
:style="{ '--start':b.start, '--duration':b.end-b.start}"
:class="{ 'canceled':b.canceled }"
>{{b.title}}
</book>
</ul>
</div>
<div class="decor table" style="width:100%;">
<ul v-for="r in resources">
<label>{{r.name}}</label>
<li v-for="t in timeRange"></li>
</ul>
</div>
</div>
</div>
</td>
</tr>
</table>
<script id="jsbin-javascript">
Vue.config.ignoredElements = ['book'];
new Vue({
el: '#sm-calendar',
data: {
resources: [
{
"name": "Room1",
"status": "active"
}, {
"name": "Room2",
"status": "active"
}, {
"name": "Room3",
"status": "active"
}, {
"name": "Room4",
"status": "active"
}
],
books: {
"Room1": [{
"start": 60,
"end": 120,
"title": "Тайская изюминка"
}],
"Room2": [{
"start": 120,
"end": 240,
"title": "Тайская изюминка",
"canceled": true
}]
},
start: 10,
end: 20,
timeRange: 10
}
/*methods: {
add: !->
this.items.push {text: this.todoText}
this.todoText = ''
delete: (ev) !->
this.items.remove ev.targetVM.$data
deleteAll: !->
#e = this.items
#pop = e.pop.bind e
#[0 to e.length].forEach pop
this.items = []
}*/
});
</script>
<script id="jsbin-source-html" type="text/html"><html>
<body>
<script src="https://unpkg.com/vue@latest/dist/vue.js"><\/script>
<table id="sm-calendar" border="0" class="sm-calendar table" style="table-layout:fixed; width:100%;height:100%;">
<tr>
<td class="labels" style="width:50px;">
<ul>
<label>#</label>
<li v-for="t in timeRange">{{t+10}}:00</li>
</ul>
</td>
<td class="items ">
<div class="scroll">
<div class="scroll_container">
<div class="books table" style="width:100%;">
<ul v-for="r in resources">
<book v-for="b in books[r.name]" key="r.name"
:style="{ '--start':b.start, '--duration':b.end-b.start}"
:class="{ 'canceled':b.canceled }"
>{{b.title}}
</book>
</ul>
</div>
<div class="decor table" style="width:100%;">
<ul v-for="r in resources">
<label>{{r.name}}</label>
<li v-for="t in timeRange"></li>
</ul>
</div>
</div>
</div>
</td>
</tr>
</table>
</body>
</html>
</script>
<script id="jsbin-source-css" type="text/css">html,body {
height:300px;
width:756px;
font-family:monospace;
}
/********* reseting ************/
ul,li {
padding: 0;
margin: 0;
list-style: none;
box-sizing:border-box;
}
td {
padding:0;
}
/*********************/
.scroll {
width: 100%; height: 100%; overflow-x: scroll; position:relative;
}
.scroll_container {
position:absolute;
left:0;
right:0;
top: 0;
bottom: 0;
}
/*********CALENDAR************/
.table {
display:table;
border-spacing:0;
border-collapse:collapse;
padding:0;
margin:0;
box-sizing:border-box;
}
.labels ul, .items .decor ul:not(:last-child) {
border-right:1px solid rgba(0,0,0,0.05);
}
.items ul {
display: table-cell;
/*overflow:hidden;*/
position:relative;
}
ul > label {
display:list-item;
background-color:rgba(0,0,0,0.15);
}
.items .decor li,
.labels li,
ul > label
{
border-bottom:1px solid rgba(0,0,0,0.15);
height:var(--reservation-height);
}
.items ul {
min-width:200px;
overflow:hidden;
}
/*****************************/
.sm-calendar {
--reservation-height: 25px;
--duration : 30; /* defaul minimal duration is 30*/
--start : 1; /* minutes, start 10:00 */
--precision : 30; /*[30min] 1800 sec in 30min*/
}
.sm-calendar {
border:1px solid #ccc;
}
.sm-calendar td {
vertical-align:top;
}
/******************/
.decor, .books {
position:absolute;
height: 100%;
}
.books ul, .books li {
}
/********* FX *********/
.items li:hover {
background:rgba(255,0,0,0.5);
}
book:hover {
background:rgba(0,0,255,0.5);
}
/******************/
book {
display:inline-block;
box-sizing:border-box;
overflow: hidden;
/*max-width: 200px;*/
width: 100%;
background:#ccc;
top:calc(var(--reservation-height) * var(--start)/var(--precision));
min-height:calc(var(--reservation-height) * var(--duration)/var(--precision)); /* actual height, для плавного отрытия */
max-height:calc(var(--reservation-height) * var(--duration)/var(--precision));/* actual height */
z-index: 16;
position: absolute; /* why not ? */
opacity:0.8;
cursor:pointer;
}
/******************/
book.canceled {
opacity:0.5;
z-index:-2;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">Vue.config.ignoredElements = ['book'];
new Vue {
el: '#sm-calendar',
data: {
resources: [
{"name":"Room1", "status":"active"},
{"name":"Room2", "status":"active"},
{"name":"Room3", "status":"active"},
{"name":"Room4", "status":"active"}
],
books : {
"Room1" : [{"start":60, "end":120, "title": "Тайская изюминка"}],
"Room2" : [{"start":120, "end":240, "title": "Тайская изюминка", "canceled":true }]
},
start:10,
end:20,
timeRange : 10
},
/*methods: {
add: !->
this.items.push {text: this.todoText}
this.todoText = ''
delete: (ev) !->
this.items.remove ev.targetVM.$data
deleteAll: !->
#e = this.items
#pop = e.pop.bind e
#[0 to e.length].forEach pop
this.items = []
}*/
}
</script></body>
</html>
html,body {
height:300px;
width:756px;
font-family:monospace;
}
/********* reseting ************/
ul,li {
padding: 0;
margin: 0;
list-style: none;
box-sizing:border-box;
}
td {
padding:0;
}
/*********************/
.scroll {
width: 100%; height: 100%; overflow-x: scroll; position:relative;
}
.scroll_container {
position:absolute;
left:0;
right:0;
top: 0;
bottom: 0;
}
/*********CALENDAR************/
.table {
display:table;
border-spacing:0;
border-collapse:collapse;
padding:0;
margin:0;
box-sizing:border-box;
}
.labels ul, .items .decor ul:not(:last-child) {
border-right:1px solid rgba(0,0,0,0.05);
}
.items ul {
display: table-cell;
/*overflow:hidden;*/
position:relative;
}
ul > label {
display:list-item;
background-color:rgba(0,0,0,0.15);
}
.items .decor li,
.labels li,
ul > label
{
border-bottom:1px solid rgba(0,0,0,0.15);
height:var(--reservation-height);
}
.items ul {
min-width:200px;
overflow:hidden;
}
/*****************************/
.sm-calendar {
--reservation-height: 25px;
--duration : 30; /* defaul minimal duration is 30*/
--start : 1; /* minutes, start 10:00 */
--precision : 30; /*[30min] 1800 sec in 30min*/
}
.sm-calendar {
border:1px solid #ccc;
}
.sm-calendar td {
vertical-align:top;
}
/******************/
.decor, .books {
position:absolute;
height: 100%;
}
.books ul, .books li {
}
/********* FX *********/
.items li:hover {
background:rgba(255,0,0,0.5);
}
book:hover {
background:rgba(0,0,255,0.5);
}
/******************/
book {
display:inline-block;
box-sizing:border-box;
overflow: hidden;
/*max-width: 200px;*/
width: 100%;
background:#ccc;
top:calc(var(--reservation-height) * var(--start)/var(--precision));
min-height:calc(var(--reservation-height) * var(--duration)/var(--precision)); /* actual height, для плавного отрытия */
max-height:calc(var(--reservation-height) * var(--duration)/var(--precision));/* actual height */
z-index: 16;
position: absolute; /* why not ? */
opacity:0.8;
cursor:pointer;
}
/******************/
book.canceled {
opacity:0.5;
z-index:-2;
}
Vue.config.ignoredElements = ['book'];
new Vue({
el: '#sm-calendar',
data: {
resources: [
{
"name": "Room1",
"status": "active"
}, {
"name": "Room2",
"status": "active"
}, {
"name": "Room3",
"status": "active"
}, {
"name": "Room4",
"status": "active"
}
],
books: {
"Room1": [{
"start": 60,
"end": 120,
"title": "Тайская изюминка"
}],
"Room2": [{
"start": 120,
"end": 240,
"title": "Тайская изюминка",
"canceled": true
}]
},
start: 10,
end: 20,
timeRange: 10
}
/*methods: {
add: !->
this.items.push {text: this.todoText}
this.todoText = ''
delete: (ev) !->
this.items.remove ev.targetVM.$data
deleteAll: !->
#e = this.items
#pop = e.pop.bind e
#[0 to e.length].forEach pop
this.items = []
}*/
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment