Skip to content

Instantly share code, notes, and snippets.

@e1blue
Created July 12, 2018 14:58
Show Gist options
  • Select an option

  • Save e1blue/e565b98e71043d6e4e4dbc94e8b48ee0 to your computer and use it in GitHub Desktop.

Select an option

Save e1blue/e565b98e71043d6e4e4dbc94e8b48ee0 to your computer and use it in GitHub Desktop.
vue.js - order and filter list animation
<div id="app">
<div class="search">
<div class="icon">
<div class="circle"></div>
<div class="bar"></div>
</div>
<div class="search-input">
<input type="text" placeholder="Search..." v-model="searchQuery">
</div>
</div>
<div class="table-container">
<table>
<thead>
<tr>
<th class="small center" @click="sort('position','asc')">#</th>
<th class="medium center"></th>
<th class="large" @click="sort('teamName','asc')" >Club</th>
<th class="medium center" @click="sort('points','asc')">Pts</th>
<th class="medium center" @click="sort('goalDifference','desc')">Diff</th>
</tr>
</thead>
<tbody name="fade-list" is="transition-group">
<tr v-for="team in filteredBySearch" :key="team.position">
<td class="small center">{{team.position}}</td>
<td class="medium"><img :src="team.crestURI" alt=""></td>
<td class="large">{{team.teamName | removeFC }}</td>
<td class="medium center">{{team.points}}</td>
<td class="medium center">
<i v-if="team.goalDifference>0">+</i>{{team.goalDifference}}
</td>
</tr>
</tbody>
</table>
<div class="warning" v-if="filteredBySearch.length<=0">
<span>No results found.</span>
</div>
</div>
</div>
new Vue({
el: '#app',
data: {
teams:[],
orderBy:'position',
orderOption:'asc',
searchQuery:''
},
mounted(){
fetch('//www.json-generator.com/api/json/get/bVBaIjVvZu?indent=2')
.then(response => response.json())
.then(json => {
this.teams = json.standing
})
},
methods:{
sort: function(by,option) {
if(this.orderBy == by){
if(this.orderOption == 'asc'){
this.orderOption = 'desc'
} else if (this.orderOption == 'desc') {
this.orderOption = 'asc'
}
} else {
this.orderOption=option;
this.orderBy=by;
}
}
},
computed:{
filteredBySearch: function () {
let self = this
return this.sortedTeams.filter((team) => (
team.teamName.replace(' FC','').toLowerCase().indexOf(self.searchQuery.toLowerCase()) !== -1
)
)
},
sortedTeams: function () {
return _.orderBy(
this.teams,
this.orderBy,
this.orderOption
)
}
},
filters:{
removeFC:function(name){
return name.replace(' FC','')
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
*{
box-sizing:border-box;
}
td img{
height:75%;
display: block;
margin-left: auto;
margin-right: auto;
}
body{
margin:0;
display:flex;
justify-content:center;
align-items:center;
background:#00ff85;
height:100vh;
cursor: default;
}
table{
font-family:'helvetica';
font-weight:600;
border-collapse: collapse;
color:#ffffff;
}
#app{
height:75%;
display:flex;
flex-direction:column;
justify-content:center;
box-shadow: 10px 10px 50px rgba(0,0,0,0.5);
}
.table-container{
padding:25px 40px;
padding-top:0px;
background-color:#38003c;
height:calc(100% - 40px);
overflow-y:scroll;
position:relative;
min-width:516px;
}
th{
color:#00ff85;
cursor:pointer;
}
th:hover{
text-decoration:underline;
}
tbody tr:hover{
background-color: #ffffff;
}
tbody tr:hover td{
color: #38003c !important;
}
tbody tr{
padding:0 5px;
}
td,th{
height:35px;
text-align:left;
padding:0 10px;
}
.table-container::-webkit-scrollbar-track
{
background-color: #38003c;
}
.table-container::-webkit-scrollbar
{
width: 5px;
/* background-color: #F5F5F5; */
}
.table-container::-webkit-scrollbar-thumb
{
background-color: #ffffff;
}
.fade-list-move {
transition: transform 0.25s ease;
}
.fade-list-leave-to {
transition: all 0.5s ease;
opacity: 0;
}
.search{
padding:15px 40px;
display:flex;
z-index:1;
width:100%;
background:#38003c;
position:relative;
padding-bottom:15px;
}
.search .icon{
min-width:50px;
height:50px;
position:relative;
}
.search .circle{
position:absolute;
width:15px;
height:15px;
border:3px solid #ffffff;
border-radius:50px;
top:15px;
left:15px;
}
.search .bar{
width:3px;
height:10px;
background:#ffffff;
transform-origin:center top;
transform: rotateZ(-45deg);
position:absolute;
bottom:12px;
right:21px;
border-radius:50px;
}
.search-input{
width:100%;
background:#38003c;
display:flex;
height:50px;
}
.search-input input{
margin:auto;
width:100%;
height:100%;
margin:0;
border:0;
padding-left:1px;
padding-right:15px;
vertical-align:middle;
white-space:normal;
background:none;
line-height:1;
border-radius:50px;
color:#ffffff;
font-family:'helvetica';
font-size:1rem;
}
.search-input input:focus{
outline:0;
}
.search-input input::placeholder{
color:rgba(255,255,255,0.25)
}
.small{
min-width:38px;
}
.medium{
min-width:48px;
}
.large{
min-width:250px;
}
.center{
text-align:center;
}
thead{
position:fixed;
background:#38003c;
z-index:10;
}
tbody{
position:absolute;
top:35px;
padding-bottom:25px;
}
.warning{
height:100%;
display:flex;
align-items:center;
justify-content:center;
font-family: 'helvetica';
font-size: 1rem;
color:#ffffff;
font-weight:bold;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment