Vue two way scroll table + dragndrop
2 way scrollable table with fixed header and row header Row header drag and drop in row spots (https://github.com/cameronhimself/vue-drag-drop/)
by leonsaysHi
HTML
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://unpkg.com/vue-drag-drop"></script>
<div id="app">
<div class="engagements">
<div class="header-wrapper row">
<div class="pro cell">
Professionals
</div>
<div class="col-headers row -scroll-h" ref="hscroll">
<div v-for="ev in eventsList" class="cell">
{{ ev.name }}
</div>
</div>
</div>
<div class="body-wrapper row">
<div class="pro body-fixed">
<div class="-scroll-v" ref="vscroll">
<div v-for="pr in professionalsList" class="cell">
<drag class="dragpro"
v-on:dragstart="currentlyDraggedPro = pr.id"
v-on:dragend="onDragend"
>:: {{ pr.firstName }} - {{ pr.lastName }}</drag>
</div>
</div>
</div>
<div class="body-scrolled" ref="body">
<div class="body">
<div v-for="pr in professionalsList" class="row">
<div v-for="ev in eventsList" class="cell">
<div @click="toggleAttendee(pr, ev)" class="droppro" :class="{'-attend': isAttending(pr, ev), '-disabled': isDisabledSpot(pr), '-isover': isOveredSpot(pr, ev) }">
<drop
@drop="handleDrop(pr, ev)"
v-on:dragover="currentlyOverSpot = { pro: pr.id, event: ev.id }"
v-on:dragleave="currentlyOverSpot = null"
></drop>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<ul>
<li v-for="ev in eventsList"><strong>{{ ev.name }}<strong>: {{ ev.professionalsList.length }} attendee(s)</li>
</ul>
<hr>
{{ currentlyOverSpot }}
</div>
SCSS
body {
font-family: sans-serif;
font-size: 12px;
* {
box-sizing: border-box;
}
}
$col-w: 100px;
$row-header-w: 200px;
.engagements {
position: relative;
.row {
display: flex;
align-items: stretch;
> * {
flex: 0 0 $col-w;
&.pro {
flex-basis: $row-header-w;
}
&.col-headers, &.body-scrolled {
flex: 1 0 0;
}
}
}
.cell {
height: 25px;
padding: 4px;
}
.-scroll-h, .-scroll-v {
overflow: hidden;
}
.header-wrapper {
.cell {
background-color: #dedede;
}
}
.body-wrapper {
height: 150px;
overflow: hidden;
.body-fixed {
&:after{
content: '';
display: block;
border-top: solid 1px #dedede;
}
}
.body-scrolled {
display: flex;
height: 150px;
flex-direction: column;
overflow: scroll;
}
}
.dragpro {
display: inline-block;
}
.droppro {
position: relative;
display: block;
height: 15px;
background-color: rgba(black, .2);
cursor: pointer;
> div {
height: 100%;
}
&.-attend {
background-color: red;
}
&.-isover {
background-color: #c38b8b;
}
&.-disabled {
opacity: .15;
}
}
}
Vue
new Vue({
el: "#app",
data: {
currentlyDraggedPro: null,
currentlyOverSpot: null,
engagementPlan:"a5T1D0000004I3qUAE",
eventsList:[
{"id":"a0p1D00000046C1QAI","planId":"a5T1D0000004I3qUAE","name":"Event 0","startDate":null,"endDate":null,"color":"#EDB550","professionalsList":[{"id":"0011D000002mkdsQAA","firstname":"MARK","lastname":"POCHAPIN","kol":"1","region":"","country":"US-United States of America","productList":[]},{"id":"0011D000002mkj6QAA","firstname":"LIN","lastname":"CHEN","kol":"1","region":"Africa/Middle East","country":"US-United States of America","productList":[{"thoughtLeadership":"National","segmentation":"Prevnar Vaccines - Pediatric"},{"thoughtLeadership":"Local","segmentation":"Prevnar Vaccines - Adult"},{"thoughtLeadership":"National","segmentation":"Infectious Disease - Antibacterial"},{"thoughtLeadership":"Global","segmentation":"Prevnar Vaccines - Adult"},{"thoughtLeadership":"Global","segmentation":"null"},{"thoughtLeadership":"Global","segmentation":"null"}]}]},
{"id":"a0p1D000000KM0GQAW","planId":"a5T1D0000004I3qUAE","name":"Event 1","startDate":null,"endDate":null,"color":"#EDB550","professionalsList":[{"id":"0011D000002mkdnQAA","firstname":"RAY","lastname":"PARKER","kol":"1","region":"","country":"AD-Andorra","productList":[]}]},
{"id":"a0p1D000000KM0GQAZ","planId":"a5T1D0000004I3qUAE","name":"Event 2","startDate":null,"endDate":null,"color":"#EDB550","professionalsList":[{"id":"0011D000002mkdnQAA","firstname":"RAY","lastname":"PARKER","kol":"1","region":"","country":"AD-Andorra","productList":[]}]},
{"id":"a0p1D000000KM0GQA1","planId":"a5T1D0000004I3qUAE","name":"Event 3","startDate":null,"endDate":null,"color":"#EDB550","professionalsList":[]},
{"id":"a0p1D000000KM0GQA2","planId":"a5T1D0000004I3qUAE","name":"Event 4","startDate":null,"endDate":null,"color":"#EDB550","professionalsList":[]}
],
professionalsList: [
...