Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Custom Tab View

Custom Tab View

Custom Tab View with hide and seek search

The Task

We need to make a list of files look cool.

  1. Toggle the files as tiles and list view.
  2. We need to be able to toggle between list and tile view on the screen.
  3. Bonus: add a filter or search method
  4. Visually we are going for if Microsoft had a baby with Apple
  5. All client side stuff / hard coding is cool
  6. Should be responsive
  7. Layout as you think best
  8. Style as you wish
  9. Namespacing things… it’s important

The Result

You can see the result online at CodePen.io. What you see is a customized tab view with a search field above. The search field responses immediately to the given input. So, if you start typing, items in the tab views not matching the given string are sorted out. Below the search field you see the interface for the tab views. For simplicity, I decided to use buttons labeled just with icons which represent the according view best. Finally, under the buttons, you find the tab views. The first one is the list view the other one is the tile view.

Resources

Libraries & Frameworks

Fonts

Tools

A Pen by Peter Sekan on CodePen.

License.

<main>
<div class="container">
<div class="jumbotron text-xs-center">
<h1 class="h2 text-center">
Custom Tab View
</h1>
<p class="lead">
with hide and seek search.
</p>
<p><small>by <a href="http://petersekan.de">Peter Sekan</a></small></p>
</div>
<input class="form-control text-xs-center" type="search" data-toggle="hideseek" id="search" data-list=".stack" value="" placeholder="Search for name or file extension">
<!-- Nav tabs -->
<div class="center-wrapper center-block">
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="nav-item">
<a class="nav-link active" href="#list" aria-controls="list" role="tab" data-toggle="tab">
<i class="fa fa-th-list fa-lg"></i>
</a>
</li>
<li class="nav-item " role="presentation">
<a class="nav-link" href="#grid" aria-controls="grid" role="tab" data-toggle="tab">
<i class="fa fa-th-large fa-lg"></i>
</a>
</li>
</ul>
</div>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="list">
<div class="table-responsive">
<table id="file-list" class="table">
<thead>
<tr>
<th>Filename</th>
<th>Size</th>
</tr>
</thead>
<tbody class=" stack">
<!-- generated content comes here -->
</tbody>
</table>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="grid">
<div id="file-grid" class="stack">
<!-- generated content comes here -->
</div>
</div>
</div>
</div>
</main>
<footer class="text-xs-center">
<small>Made with ❤︎ in</small>
<h2 class="h6 ">Berlin</h2>
</footer>
<!-- underscore templates -->
<script id="list-item" type="text/html">
<tr>
<td class="list-item-title">
<h4 class="h6 list-item-title <%= file_ext %>">
<%= title %>.<%= file_ext %>
</h4>
</td>
<td class="list-item-size">
<%= size %>
</td>
</tr>
</script>
<script id="grid-item" type="text/html">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
<div class="card">
<img class="card-img" data-src="<%= picture %>" src="<%= picture %>" alt="Card image cap">
<div class="card-img-overlay" style="background-image: url(<%= picture %>)">
<h4 class="h6 card-title text-xs-center <%= file_ext %>">
<%= title %>.<%= file_ext%>
</h4>
<p class="card-text text-xs-right">
<%= size %>
</p>
</div>
</div>
</div>
</script>
/* global _, console */
(function($) {
var $listContainer = $('#file-list tbody'),
$gridContainer = $('#file-grid');
function displayFiles() {
// JSON editor URL http://beta.json-generator.com/4y_QDzceZ
var requestURL = 'http://beta.json-generator.com/api/json/get/4y_QDzceZ',
listItems = [],
gridItems = [];
$.getJSON(requestURL, function(json) {
if (!json) {
console.log('ERROR: No Data Found!');
} else {
$.each(json, function(index) {
//console.log(json[index]);
var currentListItem = _.template($('#list-item').html()),
currentGridItem = _.template($('#grid-item').html());
listItems.push(currentListItem(json[index]));
gridItems.push(currentGridItem(json[index]));
});
$listContainer.append(listItems.join(''));
$gridContainer.append(gridItems.join(''));
// $listContainer.hide();
}
});
}
// code
function init() {
displayFiles();
$('#search').hideseek();
}
init();
}(jQuery));
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://raw.githubusercontent.com/vdw/HideSeek/master/jquery.hideseek.js"></script>
// variables
@text-color-dark: #333333;
@text-color-light: #fafafa;
@background-color-light: mediumturquoise;
@background-color-dark: lightseagreen;
// mixins
.placeholder-type() {
text-align: center;
font-size: 1.2rem;
font-family: 'Fairplay Display', serif;
font-style: italic;
letter-spacing: .02em;
color: @text-color-dark !important;
}
.before-icon( @icon:'\f15b', @size: 16px, @color: @text-color-light ) {
color: @color;
content: @icon;
font-size: @size;
font-family: "FontAwesome";
}
.grid-icon(@icon: '\f15b') {
display: block;
margin-bottom: 1rem;
.before-icon(@icon, 5rem)
}
.list-icon(@icon: '\f15b') {
display: inline-block;
margin-right: 1rem;
.before-icon(@icon, 1rem)
}
.type-sans( @color: currentColor ){
color: @color;
font-family: 'Montserrat', sans-serif;
letter-spacing: .02em
}
.type-serif( @color: currentColor ){
color: @color;
font-family: 'Fairplay Display', serif;
font-style: italic;
letter-spacing: .02em
}
// styling
// typography genearal
input::-webkit-input-placeholder {
.placeholder-type();
}
input:-webkit-input-placeholder {
.placeholder-type();
}
input:-moz-placeholder {
.placeholder-type();
}
input::-moz-placeholder {
.placeholder-type();
}
input:-ms-input-placeholder {
.placeholder-type();
}
.h2,
.h6,
th {
.type-sans();
}
.lead,
small {
.type-serif();
}
body {
color: @text-color-dark;
background-color: @background-color-light;
}
main {
padding: 1.5rem 0
}
// jumbotron styling
.jumbotron {
background-color: transparent;
border: solid 1px @background-color-dark;
}
small a {
color: currentColor;
border-bottom: solid 1px @text-color-light;
padding: 0 .25rem;
&:hover {
text-decoration: none;
color: @text-color-light;
border-color: @text-color-dark;
}
}
// search field
input[type='search'] {
.type-serif(@text-color-light);
font-size: 1.5rem;
background: none;
border: none;
border-radius: 0;
border-bottom: solid 2px @text-color-light;
&:focus {
border-bottom: solid 1px @background-color-dark;
}
}
// tab navigation styling
.center-wrapper {
overflow: hidden;
width: 12em;
padding: 2em;
}
.nav-pills .nav-link {
color: @text-color-dark;
background-color: transparent;
&.active{
background-color: transparent;
box-shadow: inset 0 0 10px 0 @background-color-dark;
color: @text-color-light;
}
&:hover {
color: @text-color-light
}
&:hover,
&:visited,
&:focus {
background-color: transparent;
&.active {
background-color: transparent;
}
}
}
// grid view styling
.card {
overflow: hidden;
border: none;
.card-img-overlay {
background-color: @background-color-light;
background-position: center;
background-blend-mode: screen;
}
&:hover {
.card-img-overlay {
background-blend-mode: normal;
}
}
}
.card-title{
&.pdf::before {
.grid-icon('\f1c1');
}
&.xls::before {
.grid-icon('\f1c3');
}
&.doc::before {
.grid-icon('\f1c2');
}
&.ppt::before {
.grid-icon('\f1c4')
}
&.png::before,
&.jpg::before{
.grid-icon('\f1c5');
}
}
.card-text,
.list-item-size {
.type-serif;
color: @text-color-light;
}
// list view styling
.list-item-title {
&.pdf::before {
.list-icon('\f1c1');
}
&.xls::before {
.list-icon('\f1c3');
}
&.doc::before {
.list-icon('\f1c2');
}
&.ppt::before {
.list-icon('\f1c4')
}
&.png::before,
&.jpg::before{
.list-icon('\f1c5');
}
}
.table td,
.table th,
.table thead th {
border-bottom: 1px solid @background-color-dark;
}
.table th {
.type-serif(@background-color-dark);
border-top: none;
}
footer {
background-color: @background-color-dark;
color: @text-color-dark;
padding: 1em 0;
margin: 0;
.h6 {
color: @text-color-light;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Montserrat|Playfair+Display:400italic" rel="stylesheet" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment