JSFiddle - React, Tailwind, and code Playground
by bowheart
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<div id="pageWrapper">
<div id="pageHeader"></div>
<div id="pageBody"></div>
</div>
<script type="text/template" id="view-1-tpl">
<div id="headerLvl-2">
<span id="goPrevPage" class="navToPage"><span class="size1">Go To </span><span class="size3">Prev</span><span class="size2">ious page</span></span>
<span id="headerText">Main Header</span>
<span id="goNextPage" class="navToPage"><span class="size1">Go To </span><span class="size3">Next</span><span class="size2"> page</span></span>
</div>
<div id="mainMenu">
<ul id="mainMenuItems">
<% _.each(pages, function(page, index) { %>
<li class="mainMenuItem"><a pageNum="<%= index %>"><%= page.pageName %></a></li>
<% }); %>
</ul>
</div>
</script>
<script type="text/template" id="pizzas-view-tpl">
<div id="viewPizzas" class="page">
<div id="subPageHeader">
<h2>Available Pizzas:</h2>
</div>
<table>
<thead>
<tr>
<th rowspan="2">Pizza Name</th>
<th rowspan="2">Primary Ingredient</th>
<th rowspan="2">Secondary Ingredient</th>
<th rowspan="2">Other Ingredients</th>
<th colspan="4">Prices</th>
</tr>
<tr>
<th>Small</th>
<th>Medium</th>
<th>Large</th>
<th>Family</th>
</tr>
</thead>
<tbody>
<% _.each(pizzas.models, function(pizza) { %>
<tr>
<td><%=...
CSS
body {
margin: 0;
}
h1, h2, h3, h4, h5, h6 {
margin: 1.5em 0 0.4em;
white-space: nowrap;
}
i.fa {
color: #555;
cursor: pointer;
}
i.fa:hover {
color: #888;
}
input {
margin: 0 0.2em 0.4em;
transition: all 0.3s;
}
input[type="button"] {
cursor: pointer;
-webkit-user-select: none;
}
table {
border: 1px solid #ccc;
border-collapse: collapse;
}
th, td {
border: 1px solid #999;
padding: 0.2em 0.4em;
}
table.noBorders, table.noBorders th, table.noBorders td {
border: none;
padding: 0.7em 0.4em;
}
th ul, td ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.error {
box-shadow: 0 0 3px 3px #e66;
}
#pageWrapper {
width: 100%;
height: 100vmax;
}
#pageHeader {
background-color: #efe;
height: 8em;
position: relative;
width: 100%;
}
#headerLvl-2 {
height: 3em;
position: absolute;
text-align: center;
top: 2em;
-webkit-animation: balloonFadeIn 0.5s;
-webkit-user-select: none;
width: 100%;
}
.navToPage {
display: block;
padding: 0.2em 0.5em;
position: absolute;
top: 0;
}
.navToPage:hover {
background-color: #dde;
border-radius: 100%;
box-shadow: 0 0 1px 2px #ccf;
cursor: pointer;
}
#goPrevPage {
left: 2.5em;
}
#goNextPage {
right: 2.5em;
}
/************** Main Menu **************/
#mainMenu {
background-color: #c94;
position: absolute;
top: 5em;
height: 3em;
text-align: center;
-webkit-user-select: none;
width: 100%;transition: all 0.25s ease-in-out;
}
#mainMenuItems {
list-style-type: none;
margin: 0;
padding: 0;
}
.mainMenuItem {
display: inline-block;
}
.mainMenuItem a {
cursor: pointer;
display: block;
height: 1em;
padding: 1em 1.3em;
transition: all 0.25s ease-in-out;
}
.mainMenuItem:not(.currentPage) a:hover {
background-color: #fce;
border-radius: 4px;
}
.mainMenuItem.currentPage {
background-color:...
JavaScript
var Pizza = Backbone.Model.extend({
initialize: function(data) {
this.set({
name: data.name,
mainIngredient: data.mainIngredient,
secondaryIngredient: data.secondaryIngredient,
otherToppings: data.otherToppings,
sizePrices: {
small: data.basePrice,
medium: Number((data.basePrice * 1.5).toFixed(2)),
large: Number((data.basePrice * 1.95).toFixed(2)),
family: Number((data.basePrice * 2.3).toFixed(2))
}
});
},
defaults: {
name: "",
mainIngredient: "",
secondaryIngredient: "",
otherToppings: [],
sizePrices: {
small: 0,
medium: 0,
large: 0,
family: 0
}
}
});
var PizzaCollection = Backbone.Collection.extend({
model: Pizza
});
var Collection_2 = Backbone.Collection.extend({
model: Pizza
});
var View_1 = Backbone.View.extend({
el: "#pageWrapper",
template: _.template($('#view-1-tpl').html()),
initialize: function(pages) {
var view = this;
view.pages = pages;
view.currentPage = 0;
view.render();
view.pages[view.currentPage].render();
view.highlightPageInMenu();
},
events: {
"click #goPrevPage": "goToPrevPage",
"click #goNextPage": "goToNextPage",
"click .mainMenuItem": "goToPage"
},
changePage: function(targetPage) {
var view = this;
$('.page').addClass('fadeOut');
setTimeout(function() {
view.pages[targetPage].render();
view.currentPage = targetPage;
view.highlightPageInMenu();
}, 400);
},
goToNextPage: function() {
var view = this;
var nextPage = view.currentPage + 1;
if (nextPage >= view.pages.length) nextPage = 0;
view.changePage(nextPage);
},
...