Tabs Component Recipe
HTML
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http:////canjs.com/release/2.0.4/can.jquery.js"></script>
<script type="text/mustache" id="app-template">
<tabs>
<panel title="Fruit">Oranges, Apples, Pears</panel>
<panel title="Vegetable">Carrot, Lettuce, Rutabega</panel>
<panel title="Grains">Bread, Pasta, Rice</panel>
</tabs>
</script>
<!-- CanJS needs a place to put your application -->
<div id="my-app"></div>
CSS
ul {
list-style: none;
padding-left: 0px;
}
li{
display: inline-block;
padding: 5px;
border: 1px solid black;
-webkit-border-top-left-radius: 8px;
-webkit-border-top-right-radius: 8px;
-moz-border-radius-topleft: 8px;
-moz-border-radius-topright: 8px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
cursor: pointer;
}
.panelcontent {
border: 1px solid black;
}
JavaScript
var TabsViewModel = can.Map.extend({
panels: [],
active: null,
addPanel: function( panel ){
var panels = this.attr("panels");
panels.push(panel);
panel.attr("visible", false);
//activate panel if it is the first one
if ( panels.attr("length") === 1 ){
this.activate( panel );
}
},
removePanel: function( panel ){
var panels = this.attr("panels");
var index = panels.indexOf(panel);
panels.splice(index, 1);
//activate a new panel if panel being removed was the active panel
if( this.attr("active") === panel ){
panels.attr("length") ? this.activate(panels[0]) : this.attr("active", null)
}
},
activate: function( panel ){
var active = this.attr("active")
if( active !== panel ){
active && active.attr("visible", false);
this.attr("active", panel.attr("visible", true));
}
}
})
can.Component.extend({
tag: "tabs",
scope: TabsViewModel,
template: "<ul>\
{{#each panels}}\
<li can-click='activate'>{{title}}</li>\
{{/each}}\
</ul>\
<content />"
});
can.Component.extend({
tag: "panel",
template: "{{#if visible}}<content />{{/if}}",
scope: {
title: "@"
},
events: {
inserted: function() {
this.element.parent().scope().addPanel( this.scope )
},
removed: function() {
this.element.parent().scope().addPanel( this.scope )
}
}
});
var frag = can.view("app-template", {});
$("#my-app").html(frag);