JSFiddle - React, Tailwind, and code Playground
by tonyleeper
HTML
<div class="campaign-calendar">
<h1>CAMPAIGN CALENDAR</h1>
<div class="background-header"></div>
<div class="content">
<div class="ribbon">
<div class="filter">
<button class="toggle-filter" data-bind="click: toggleFilter">F</button>
<div class="filter-flyout" data-bind="visible: filterOpened()">
<div class="menu" tabindex="0">
<ul>
<li data-bind="click: function () { filter.activeMenu('states') }">State</li>
<li data-bind="click: function () { filter.activeMenu('owners') }">Owner</li>
</ul>
</div>
<div class="options">
<ul class="states" tabindex="0" data-bind="foreach: filter.menuOptions.states(),
visible: $root.filter.activeMenu() === 'states'">
<li data-bind="click: function () { $data.selected(!$data.selected()); }">
<span data-bind="text: $data.selected() ? 'Y' : 'N'"></span>
<label data-bind="text: $data.name"></label>
</li>
</ul>
<ul class="owners" tabindex="0" data-bind="foreach: filter.menuOptions.owners(),
visible: $root.filter.activeMenu() === 'owners'">
<li data-bind="click: function () { $data.selected(!$data.selected()); }">
<span data-bind="text: $data.selected() ? 'Y' : 'N'"></span>
<label data-bind="text: $data.name"></label>
</li>
</ul>
</div>
</div>
</div>
<input type="text" placeholder="search..."...
CSS
* {
margin: 0;
padding: 0;
-webkit-user-select: none;
}
input {
-webkit-user-select: auto;
}
html, body {
height: 100%;
}
.campaign-calendar {
background-color: rgba(0, 0, 0, .1);
min-height: 400px;
min-width: 800px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.background-header {
background-color: #5f6570;
height: 200px;
}
.content {
position: absolute;
top: 40px;
bottom: 20px;
left: 20px;
right: 20px;
padding: 10px;
border: 1px solid rgba(0, 0, 0, .6);
-webkit-border-radius: 5px;
background-color: white;
-webkit-box-shadow: 0px 0px 10px #888888;
}
.ribbon {
padding: 8px;
height: 27px;
border: 1px solid rgba(0, 0, 0, .6);
-webkit-border-radius: 5px;
text-align: right;
}
.filter {
display: inline-block;
position: relative;
}
.toggle-filter {
padding: 4px;
}
.filter-flyout {
position: absolute;
left: -101px;
top: 27px;
width: 300px;
height: 300px;
border: 1px solid black;
background-color: white;
-webkit-box-shadow: 0px 0px 10px #888888;
z-index: 1;
display: table;
text-align: left;
cursor: default;
}
.filter-flyout .menu {
display: table-cell;
width: 100px;
background-color: #fafafa;
}
.filter-flyout .menu ul {
list-style: none;
margin: 0;
}
.filter-flyout .options {
display: table-cell;
background-color: #fafafa;
}
.filter-flyout .options ul {
list-style: none;
padding: 0;
margin: 0;
}
.info-bar {
height: 40px;
border: 1px solid rgba(0, 0, 0, .6);
-webkit-border-radius: 5px;
}
.results {
position: absolute;
top: 97px;
bottom: 10px;
left: 10px;
right: 10px;
border: 1px solid rgba(0, 0, 0, .6);
-webkit-border-radius: 5px;
overflow: auto;
}
h1 {
float: left;
margin-left: 17px;
margin-top: 13px;
color: white;
font-family: "Lucida...
JavaScript
/**
Campaign Calendar MVVM
*/
var CheckBoxOption = function (value, selected) {
this.value = ko.observable(value);
this.selected = ko.observable(!!selected);
};
var CampaignCalendarViewModel = (function () {
var CampaignCalendarViewModel = function () {
this.searchText = ko.observable();
this.filterOpened = ko.observable(false);
this.filter = {
menuOptions: {
owners: ko.observableArray(),
states: ko.observableArray(),
},
activeMenu: ko.observable("owners"),
};
this.freeTextSearchResults = [];
this.filterSearchResults = [];
var owners = this.getOwners();
for (var i = 0; i < owners.length; i++) {
this.filter.menuOptions.owners.push(owners[i]);
}
var states = this.getStates();
for (var i = 0; i < states.length; i++) {
this.filter.menuOptions.states.push(states[i]);
}
};
CampaignCalendarViewModel.prototype.getOwners = function() {
return [
{ name: "Tony", selected: ko.observable(false) },
{ name: "Suprabhat", selected: ko.observable(false) },
{ name: "Neha", selected: ko.observable(false) },
{ name: "Kallappa", selected: ko.observable(false) },
{ name: "Jaganathan", selected: ko.observable(false) },
{ name: "Mal", selected: ko.observable(false) },
{ name: "Kevin", selected: ko.observable(false) },
{ name: "Samih", selected: ko.observable(false) }
];
};
CampaignCalendarViewModel.prototype.getStates = function() {
return [
{ name: "State1", selected: ko.observable(false) },
{ name: "State2", selected: ko.observable(false) }
];
};
CampaignCalendarViewModel.prototype.toggleFilter = function () {
this.filterOpened(!this.filterOpened());
};
...